2013-02-06 35 views
1

我有2個表UserSessionSale如果存在塊

User有4列,即UserID,UserSessionID,SessionOpenDateSessionCloseDate

Sale具有2列,這是pricecostuserIDCompletedDate

當用戶登錄時,將在User表中創建一個新行,其中用戶的登錄時間戳將保存在SessionOpenDate中,並且將爲該會話分配新的UserSessionID。當用戶註銷時,註銷時間戳將被保存在SessionCloseDate中。

當用戶仍然登錄時,用戶可以進行一些銷售,並將銷售信息保存在Sale表中。銷售完成時的時間戳保存在CompletedDate列中。

由於某種原因,我需要在UserSessionID的某個UserSessionID中完成所有銷售,其中CompletedDate必須在SessionOpenDateSessionCloseDate之內。但是,如果用戶尚未註銷,這意味着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

使用'CASE WHEN'。你在「SELECT」語句中用SET來做什麼? –

回答

4

您不能使用IFSELECT語句內。另外,由於closeTime不是變量/參數,所以我不知道你真的想用SET完成什麼。

您可以在SQL Server中使用IIF 2012(語法糖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') 
+0

如果我正確記得,'IIF'只在SQL Server 2012中。 –

+0

@ ta.speot.is是的,好點。編輯。 –

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 

(你可以添加和usersessionid在=「mysessionid」或用戶名和該=組上「myuserid」的,如果你不想要的完整列表)

1

其他人解釋具體問題和「給你一條魚「。不過,我想「教你如何釣魚」。

請參閱mixed-up statement types進行全面討論(披露:我自己的博客文章)。這裏有一些片段。

一個表達式由一個或多個文字值或與操作符綁定在一起的函數組成,當它們以正確的順序進行計算時,會生成一個值或一組值。

略...

程序語句稱爲是因爲有一些步驟必須遵循。這不是操作次序導致單一值的簡單情況。實際上並沒有表達任何價值。

略...

現在你知道了三種主要的報表(我不排除有被這些沒有被亞類的更多或可能性)的關鍵您必須知道與SQL Server相處的概念是,當預期某種類型的語句時,您不能使用其他語言。

我希望這對你有幫助。