2014-02-11 24 views
-1

我想說明從哪個用戶不與某些數據進行任何tasks.My表的表中缺少日期是如何從每個用戶的表格組中找到缺失的日期?

CREATE TABLE Tasks 
    ([Name] varchar(50), [UserId] int, [TaskDate] datetime) 


INSERT INTO Tasks 
    ([Name], [UserId], [TaskDate]) 
VALUES 
    ('mickel',1, '2012-08-06 00:00:00'), 
    ('mickel',1, '2012-08-07 00:00:00'), 
    ('mickel',1, '2012-08-011 00:00:00'), 
    ('mickel',1, '2012-08-013 00:00:00'), 

    ('Joseph',2, '2012-08-06 00:00:00'), 
    ('Joseph',2, '2012-08-08 00:00:00'), 
    ('Joseph',2, '2012-08-09 00:00:00'), 
    ('Joseph',2, '2012-08-12 00:00:00'), 

    ('Shan', 3, '2012-08-07 00:00:00'), 
    ('Shan', 3, '2012-08-08 00:00:00'), 
    ('Shan', 3, '2012-08-10 00:00:00'), 
    ('Shan', 3, '2012-08-12 00:00:00') 

一個想要顯示輸出,其中每行顯示每個用戶和逗號的名稱分隔的缺失日期列表。

+0

你可以舉一些例子 – Miller

+1

你的問題很模糊的 - 你可以給什麼樣的輸出*威力*看起來像一個例子嗎?你想在SQL或C#中使用這個嗎?另外,你到目前爲止嘗試過什麼? – matt

+0

首先,你至少需要一個開始日期來檢查從 – Jonesopolis

回答

1

SQL Fiddle創建一個內嵌表值函數:

IF EXISTS (SELECT 1 
      FROM sys.objects 
      WHERE name = 'ExplodeDates' 
       AND type = 'IF') 
BEGIN 
    DROP FUNCTION dbo.ExplodeDates; 
END; 
GO 

CREATE FUNCTION dbo.ExplodeDates 
(
    @StartDate datetime, 
    @NoDays  integer 
) RETURNS TABLE AS 
RETURN (
    SELECT TOP (@NoDays) 
      DateVal = DATEADD(DAY, ROW_NUMBER() OVER (
       ORDER BY s1.object_id), @StartDate) 
    FROM sys.all_objects s1 
    CROSS JOIN sys.all_objects s2 
); 
GO 

然後使用CTE生成結果和FOR XML PATH塞住最終列。

WITH cte AS (
    SELECT u.Name, u.UserId, x.DateVal 
    FROM ( SELECT StartDate = MIN(t.TaskDate), 
        NoDays = DATEDIFF(DAY, MIN(t.TaskDate), MAX(t.TaskDate)) 
      FROM dbo.Tasks t) p 
    CROSS APPLY dbo.ExplodeDates(p.StartDate, p.NoDays) x 
    CROSS JOIN (SELECT DISTINCT Name, UserId 
       FROM dbo.Tasks) u 
    LEFT JOIN dbo.Tasks t 
     ON u.Name = t.Name 
     AND u.UserId = t.UserId 
     AND x.DateVal = t.TaskDate 
    WHERE t.Name IS NULL 
     AND t.UserId IS NULL) 
SELECT f.Name, f.UserId, LEFT(f.MissingDates, LEN(f.MissingDates) - 1) 
FROM ( SELECT c1.Name, c1.UserId, MissingDates = (
        SELECT CONVERT(VARCHAR(MAX), DateVal, 112) + ', ' 
        FROM cte c2 
        WHERE c2.Name = c1.NAME 
         AND c2.UserId = c1.UserId 
        ORDER BY c2.Name 
        FOR XML PATH(''))    
     FROM cte c1 
     GROUP BY c1.Name, c1.UserId) f 
ORDER BY f.UserId; 
1

嘗試運行此查詢:

select 
p1.userid, 
    (SELECT Convert(varchar(max),taskdate, 121) + ' and ' 
     FROM tasks p2 
     WHERE p2.userid = p1.userid 
     ORDER BY NAME 
     FOR XML PATH('')) AS NameValues from tasks p1 group by userid 
相關問題