2013-12-14 34 views
1

我在sql數據庫[dbo]中有一個表,[ClockInClockOut]有3列:[UserId],ClockInClockOutTypeId],[CreatedDate]。我需要表現出像如何在sql中使用union?

UserName CreatedDate  TimeIn  TimeOut 

abc  12/31/2013  13:19:51 13:22:37 
xyz  1/31/2013   14:19:51 15:19:51 

數據我這樣做在SQL:

select u.[UserName], 
      CONVERT(VARCHAR(20), c.[CreatedDate], 101) as [Date], 
      CASE WHEN c.[ClockInClockOutTypeId]=1 and THEN CONVERT(VARCHAR(20), c.[CreatedDate], 108) ELSE null END as InTime, 
      CASE WHEN c.[ClockInClockOutTypeId]=2 THEN CONVERT(VARCHAR(20), c.[CreatedDate], 108) ELSE null END as OutTime 
    from [ClockInClockOut] as c 
    inner join [UserProfile] as u on c.UserId = u.[UserId] 

而且我得到這個結果:

UserName CreatedDate  TimeIn  TimeOut 

    abc  12/31/2013  13:19:51 null 
    abc  12/31/2013   null  14:19:51 

第1行第3列時間沒問題,但我需要第四列的時間而不是第四列的第二行。

+2

你有一個名爲'ClockInClockOut'的未知數據庫(其名稱無關緊要)。讓你的術語直白;如果您將表格稱爲數據庫,您會迷惑自己和每個想要尋求幫助的人。 –

回答

2

您需要加入ClockInClockOut回到自己的第二個時間,而不是union the results

我會做同樣的事情到

SELECT 
    u.UserName, 
    CONVERT(VARCHAR(20), c1.[CreatedDate], 101) as [Date], 
    CONVERT(VARCHAR(20), c1.[CreatedDate], 108) as InTime, 
    CONVERT(VARCHAR(20), c2.[CreatedDate], 108) as OutTime 
FROM [ClockInClockOut] as c1 
INNER JOIN [ClockInClockOut] as c2 ON c1.UserId = c2.UserId 
      -- getting the specific date is a little tricky, unquestionably better ways exist 
      AND CONVERT(VARCHAR(20), c1.[CreatedDate], 101) = CONVERT(VARCHAR(20), c2.[CreatedDate], 101) 
INNER JOIN [UserProfile] as u on c1.UserId = u.[UserId] 
WHERE 
    c1.ClockInClockOutTypeId = 1 AND c2.ClockInClockOutTypeId = 2 

或者,如果你不喜歡,你可以收集您的初始查詢......

SELECT 
    a.UserName, a.Date 
    MAX(a.InTime) As InTime, 
    MAX(a.OutTime) As OutTime 
FROM (
    SELECT 
     u.[UserName], 
     CONVERT(VARCHAR(20), c.[CreatedDate], 101) as [Date], 
     CASE WHEN c.[ClockInClockOutTypeId]=1 and THEN CONVERT(VARCHAR(20), c.[CreatedDate], 108) ELSE null END as InTime, 
     CASE WHEN c.[ClockInClockOutTypeId]=2 THEN CONVERT(VARCHAR(20), c.[CreatedDate], 108) ELSE null END as OutTime 
    FROM[ClockInClockOut] as c 
    INNER JOIN [UserProfile] as u on c.UserId = u.[UserId] 
) a 
GROUP BY a.UserName, a.Date 
+0

完美答案謝謝@Travis –

1

測試數據

DECLARE @ClockInClockOut TABLE 
([UserId] INT, [ClockInClockOutTypeId] SMALLINT, [CreatedDate] DATETIME) 

INSERT INTO @ClockInClockOut 
VALUES 
(1,1,'2013-12-10 09:42:08.603'), 
(1,2,'2013-12-10 16:42:08.603'), 
(1,1,'2013-12-11 16:42:08.603'), 
(1,2,'2013-12-11 18:42:08.603'), 
(2,1,'2013-12-12 09:42:08.603'), 
(2,2,'2013-12-12 16:42:08.603'), 
(2,1,'2013-12-13 11:42:08.603'), 
(2,2,'2013-12-13 15:42:08.603') 

DECLARE @UserProfile TABLE (USERID INT, USERNAME VARCHAR(20)) 
INSERT INTO @UserProfile 
VALUES (1, 'Mark'), 
     (2, 'John') 

查詢

;With TimeI 
AS 
    (
    SELECT UserID, [CreatedDate], 
       CONVERT(VARCHAR(20), [CreatedDate], 108) AS InTime 
    FROM @ClockInClockOut 
    WHERE [ClockInClockOutTypeId]=1 
    ), 
TimeO 
AS 
    (
    SELECT UserID,[CreatedDate], 
       CONVERT(VARCHAR(20), [CreatedDate], 108) AS OutTime 
    FROM @ClockInClockOut 
    WHERE [ClockInClockOutTypeId]=2 
) 
SELECT DISTINCT USERNAME , CAST(CO.[CreatedDate] AS DATE) AS [CreatedDate], TI.Intime, T.OutTime 
FROM @UserProfile UP INNER JOIN @ClockInClockOut CO 
ON UP.USERID = CO.UserId 
INNER JOIN TimeI TI 
ON UP.USERID = ti.UserId 
AND CAST(CO.[CreatedDate] AS DATE) = CAST(TI.[CreatedDate] AS DATE) 
INNER JOIN TimeO T 
ON UP.USERID = t.UserId 
AND CAST(CO.[CreatedDate] AS DATE) = CAST(T.[CreatedDate] AS DATE) 

結果集

USERNAME CreatedDate  Intime  OutTime 
John   2013-12-12 09:42:08 16:42:08 
John   2013-12-13 11:42:08 15:42:08 
Mark   2013-12-10 09:42:08 16:42:08 
Mark   2013-12-11 16:42:08 18:42:08 
1

這可能是更容易使用的ClockInClockOut表自聯接,而不是試圖聯合。

SELECT u.UserName, i.Date, i.InTime, o.OutTime 
    FROM (SELECT u.UserName, 
       CONVERT(VARCHAR(20), c.CreatedDate, 101) AS Date, 
       CONVERT(VARCHAR(20), c.CreatedDate, 108) AS InTime 
      FROM ClockInClockOut AS c 
     WHERE c.ClockInClockOutTypeId = 1) AS i 
    JOIN (SELECT u.UserName, 
       CONVERT(VARCHAR(20), c.CreatedDate, 101) AS Date, 
       CONVERT(VARCHAR(20), c.CreatedDate, 108) AS InTime 
      FROM ClockInClockOut AS c 
     WHERE c.ClockInClockOutTypeId = 2) AS o 
    ON i.UserName = o.UserName AND i.Date = o.Date 
    JOIN UserProfile AS u ON i.UserId = u.UserId 

您可能需要讓加盟條件更復雜,如果你需要處理誰籤不止一次在某一天的人,或誰午夜結賬午夜後,等以前只是用於簡單籤每天換一次,一旦出現這種情況,這將起作用。