首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IF EXISTS块

IF EXISTS块
EN

Stack Overflow用户
提问于 2013-02-06 14:27:36
回答 3查看 700关注 0票数 1

我有两张桌子UserSessionSale

User有4列,分别是UserIDUserSessionIDSessionOpenDateSessionCloseDate

Sale有两列,分别是pricecostuserIDCompletedDate

当用户登录时,将在User表中创建一个新行,其中用户的登录时间戳将保存在SessionOpenDate中,并为会话分配一个新的UserSessionID。当用户注销时,注销时间戳将保存在SessionCloseDate中。

当用户仍然登录时,用户可以进行一些销售,销售信息保存在Sale表中。saved in CompletedDate列中销售完成的时间戳。

出于某些原因,我需要在某个UserSessionID中完成所有销售,其中CompletedDate必须在SessionOpenDateSessionCloseDate中。但是,如果用户尚未注销,这意味着SessionCloseDate中的值为null,则CompletedDate应该介于SessionOpenDate和now之间。

下面是我的问题:

代码语言:javascript
复制
SELECT SUM(s.cost) AS Cost, SUM(s.price) AS Price
FROM Sale AS s 
  INNER JOIN UserSession AS u 
  ON s.userID = u.userID
WHERE 
  (s.CompletedDate >=
    ( SELECT SessionOpenDate
      FROM UserSession
      WHERE (UserSessionID = u.UserSessionID)
)
  ) 
  AND 
  (s.CompletedDate < 
    ( 
      IF EXISTS
       (    
         SELECT SessionCloseDate AS closeTime
         FROM UserSession AS UserSessionTemp
         WHERE (UserSessionID = u.UserSessionID)
       ) 
       BEGIN
         SET closeTime = SELECT CURRENT_TIMESTAMP
       END
    )
  ) 
  AND u.UserSessionID IN (1) 

但是,Sql Server说的是Incorrect syntax near the keyword 'IF'.Incorrect syntax near ')'

谁能告诉我我的IF代码块出了什么问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-06 14:33:18

不能在SELECT语句中使用IF块。另外,我不知道您到底想用SET实现什么,因为closeTime不是一个变量/参数。

您可以在SQL Server 2012中使用IIF ( CASE WHEN <condition> THEN <true_value> ELSE <false_value> END的语法糖-在早期版本中使用此语法):

代码语言:javascript
复制
IIF(EXISTS
   (    
     SELECT SessionCloseDate AS closeTime
     FROM UserSession AS UserSessionTemp
     WHERE (UserSessionID = u.UserSessionID)
   ), (
     SELECT SessionCloseDate AS closeTime
     FROM UserSession AS UserSessionTemp
     WHERE (UserSessionID = u.UserSessionID)
   ),  
     CURRENT_TIMESTAMP
)

老实说,在不太复杂的情况下,以下是我要做的事情:

代码语言:javascript
复制
SELECT SUM(s.cost) AS Cost, SUM(s.price) AS Price
FROM userSession AS u
INNER JOIN Sale AS s ON u.userID = s.userID 
WHERE u.UserSessionID = @UserSessionId
AND s.CompletedDate >= u.SessionOpenDate 
AND (u.SessionCloseDate IS NULL OR s.CompletedDate < u.SessionCloseDate)

或,

代码语言:javascript
复制
SELECT SUM(s.cost) AS Cost, SUM(s.price) AS Price
FROM userSession AS u
INNER JOIN Sale AS s ON u.userID = s.userID 
WHERE u.UserSessionID = @UserSessionId
AND s.CompletedDate BETWEEN u.SessionOpenDate 
                    AND COALESCE(u.SessionCloseDate, '12/31/9999 23:59:59.9999')
票数 4
EN

Stack Overflow用户

发布于 2013-02-06 14:48:44

我会选择这样的东西,这取决于你要找的是什么。我不知道您是否需要特定用户或会话的信息,但添加这些信息非常简单。

代码语言:javascript
复制
SELECT UserSessionID, SUM(cost) AS TotalCost, SUM(price) AS TotalPrice
FROM UserSession LEFT OUTER JOIN sale
ON UserSession.userid = sale.userid AND
   ((UserSession.SessionCloseDate IS NULL AND sale.CompletedDate BETWEEN UserSession.SessionOpenDate AND GetDate())
   OR (sale.SessionCloseDate IS NOT NULL AND sale.CompletedDate BETWEEN UserSession.SessionOpenDate AND UserSession.SessionCloseDate))
WHERE SUM(cost) > 0
GROUP BY UserSessionID

(如果不想要完整的列表,可以在group by上面添加和UserSessionID = 'mysessionid‘或和UserID = 'myuserid’)

票数 2
EN

Stack Overflow用户

发布于 2013-02-06 15:06:09

其他人解释了具体的问题,并“给了你一条鱼”。不过,我想“教你如何钓鱼”。

请参阅mixed-up statement types了解完整的讨论(披露:我自己的博客帖子)。这里有一些代码片段。

表达式由一个或多个文字值或函数与运算符绑定在一起,当它们以正确的顺序计算时,会产生一个值或一组值。

斯奈普...

之所以称为

过程语句,是因为有一些必须遵循的过程。这不是一个简单的操作顺序导致单个值的情况。事实上,根本没有表达任何价值。

斯奈普...

现在您已经知道了三种主要类型的语句(我不排除这些语句有更多或子分类的可能性),为了与SQL Server和谐相处,您必须知道的关键概念是,当需要某种语句时,不能使用不同的语句来代替它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14722922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档