我有2个表UserSession
和Sale
。
表User
有4列,即UserID
,UserSessionID
,SessionOpenDate
和SessionCloseDate
。
表Sale
有2列,分别是price
,cost
,userID
和CompletedDate
。
当用户登录时,会在User
表中创建一个新行,其中用户的登录时间戳将保存在SessionOpenDate
中,并且新的UserSessionID
将被分配给会议。当用户注销时,注销时间戳将保存在SessionCloseDate
。
当用户仍然登录时,用户可以进行一些销售,销售信息保存在Sale
表中。销售最终确定的时间戳已保存在CompletedDate
列中。
由于某些原因,我需要在某个UserSessionID
内完成所有销售,其中CompletedDate
必须在SessionOpenDate
和SessionCloseDate
之内。但是,如果用户尚未注销,这意味着SessionCloseDate
中的值为空,则CompletedDate
应介于SessionOpenDate
和现在之间。
这是我的疑问:
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块出了什么问题?
由于
答案 0 :(得分:4)
您不能在IF
语句中使用SELECT
块。此外,由于SET
不是变量/参数,因此我不知道您真正想要使用closeTime
完成什么。
您可以在SQL Server 2012中使用IIF
(CASE WHEN <condition> THEN <true_value> ELSE <false_value> END
的语法糖 - 在早期版本中使用此语法):
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
)
老实说,不要太复杂,这就是我要做的事情:
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)
或者,
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')
答案 1 :(得分:2)
我会选择这样的东西,这取决于你在寻找什么。我不知道你是否想要特定用户或会话的信息,但这很简单,可以添加。
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
(如果您不想要完整列表,可以在组上方添加AND UserSessionID ='mysessionid'或UserID ='myuserid')
答案 2 :(得分:1)
其他人已经解释了具体问题和“给你一条鱼”。不过,我想“教你如何钓鱼”。
请参阅mixed-up statement types进行全面讨论(披露:我自己的博文)。这是一些片段。
表达式由一个或多个与运算符绑定在一起的文字值或函数组成,当以正确的顺序计算时,会生成值或值集合。
...剪断
调用过程语句,因为必须遵循一些过程。这不是一个简单的操作顺序,导致单个值。实际上根本没有表达任何价值。
...剪断
现在您已经了解了三种主要语句(并且我不排除存在更多或者存在更多这些语句的可能性),您必须知道与SQL Server相处的关键概念是当预期某种陈述时,你不能在其中使用不同的陈述。
我希望这对你有所帮助。