2014-04-11 15 views
1

好吧,我的標題看起來有點奇怪,但我可以找到更好的方式來標題我的問題。按用戶查詢,按月包括不存在記錄的默認值

我現在的SQL語句如下所示:

SELECT 
    ActionBy, 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0) AS 'dateStart', 
    CONVERT(CHAR(3), (DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0)), 100) AS 'Month' , 
    YEAR(ActionCreateDate) AS 'YEAR', 
    SUM([TimeTakenToComplete]) AS TOTAL 
FROM 
    [myTable] 
WHERE 
    [TimeTakenToComplete] IS NOT NULL 
    AND DeleteDate IS NULL 
    AND ActionBy IS NOT NULL 
GROUP BY 
    ActionBy, DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0), 
    YEAR(ActionCreateDate) 
ORDER BY 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0) ASC 

最終的結果看起來是這樣的:

user1 , 2013-06-01 00:00:00.000 , Jun , 2013 , 1000 
user2 , 2013-06-01 00:00:00.000 , Jun , 2013 , 998 
user3 , 2013-06-01 00:00:00.000 , Jun , 2013 , 600 
user1 , 2013-07-01 00:00:00.000 , Jul , 2013 , 1110 
user3 , 2013-07-01 00:00:00.000 , Jul , 2013 , 2330 

我的問題是,我想對所有用戶的記錄,對於所有月份的默認值爲0.

所以我希望的結果看起來像這樣:

user1 , 2013-06-01 00:00:00.000 , Jun , 2013 , 1000 
user2 , 2013-06-01 00:00:00.000 , Jun , 2013 , 998 
user3 , 2013-06-01 00:00:00.000 , Jun , 2013 , 600 
user1 , 2013-07-01 00:00:00.000 , Jul , 2013 , 1110 
user2 , 2013-07-01 00:00:00.000 , Jul , 2013 , 0 
user3 , 2013-07-01 00:00:00.000 , Jul , 2013 , 2330 

有沒有什麼辦法可以達到這個結果,還是我應該去編程解決這個問題?

+0

'user'是不是一種選擇..? –

+0

是的,它可以是... – MaVRoSCy

+0

不,它不可以。你必須檢查你的'WHERE'子句並使條件'SUM'。 –

回答

1

檢查此解決方案。它提供了所需的輸出。

此外,我已經使用表變量來模擬你的需要。我也用@Users表來考慮你有一個用戶表。如果您不想使用users表,那麼您也可以使用mytable,但在其他月份至少應該有1個失蹤用戶。

--Simulation of your myTable 
DECLARE @myTable TABLE 
(
    ActionBy VARCHAR(10), 
    ActionCreateDate DATETIME, 
    TimeTakenToComplete INT 
) 

--Simulation of users table 
DECLARE @Users TABLE 
(
    ActionBy VARCHAR(10) 
) 

--Dummy data for testing 
INSERT INTO @myTable VALUES ('user1' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user1' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user1' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user1' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user1' , '2013-06-01', 100); 

INSERT INTO @myTable VALUES ('user2' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user2' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user2' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user2' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user2' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user2' , '2013-06-01', 100); 

INSERT INTO @myTable VALUES ('user3' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-06-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-06-01', 100); 


INSERT INTO @myTable VALUES ('user1' , '2013-07-01', 100); 
INSERT INTO @myTable VALUES ('user1' , '2013-07-01', 100); 
INSERT INTO @myTable VALUES ('user1' , '2013-07-01', 100); 

INSERT INTO @myTable VALUES ('user3' , '2013-07-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-07-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-07-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-07-01', 100); 
INSERT INTO @myTable VALUES ('user3' , '2013-07-01', 100); 


INSERT INTO @Users VALUES ('user1'); 
INSERT INTO @Users VALUES ('user2'); 
INSERT INTO @Users VALUES ('user3'); 

--Actual solution starts from here 
; WITH MYCTE AS 
(SELECT 
    ActionBy, 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0) AS 'dateStart', 
    CONVERT(CHAR(3), (DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0)), 100) AS 'Month' , 
    YEAR(ActionCreateDate) AS 'YEAR', 
    SUM([TimeTakenToComplete]) AS TOTAL 
FROM 
    @myTable 
WHERE 
    [TimeTakenToComplete] IS NOT NULL 
    --AND DeleteDate IS NULL --uncomment this on using with your code 
    AND ActionBy IS NOT NULL 
GROUP BY 
    ActionBy, DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0), 
    YEAR(ActionCreateDate) 
) 

SELECT 
ISNULL(M1.ActionBy, L1.ActionBy) , 
ISNULL(M1.dateStart, L1.dateStart), 
ISNULL(M1.Month, L1.Month), 
ISNULL(M1.YEAR, L1.YEAR), 
ISNULL(M1.TOTAL, 0) 
FROM MYCTE M1 
RIGHT OUTER JOIN 
(
    SELECT * FROM 
    (
    (SELECT DISTINCT [Month], dateStart, YEAR FROM MYCTE) m 
    CROSS JOIN (SELECT ActionBy FROM @Users) U 
    ) 
)L1 
ON M1.[Month] = L1.[Month] 
AND M1.ActionBy = L1.ActionBy 

希望這會使用與您的表連接的幫助

1

其實我在等待@哈姆雷特的解決方案..
但這裏是我的想法(我還沒有嘗試運行它)..
,如果有一個月的不是任何數據任何用戶,會出現完全沒有數據(該月份)..

SELECT a.username, 
    b.dateStart, 
    b.Month , 
    b.YEAR, 
    ISNULL(result.TOTAL,0) 
FROM 
(SELECT username FROM tableUser) a CROSS JOIN 
(SELECT DISTINCT dateStart, CONVERT(CHAR(3), dateStart, 100) AS 'Month', 'YEAR' FROM result) b 
LEFT JOIN result 
ON a.username=result.ActionBy AND b.dateStart=result.dateStart 

注:我叫表從原始查詢作爲result,並在原來的查詢,你可以選擇這個:

SELECT 
    ActionBy, 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, ActionCreateDate), 0) AS 'dateStart', 
    YEAR(ActionCreateDate) AS 'YEAR', 
    SUM([TimeTakenToComplete]) AS TOTAL 
... 
1

關鍵是要開始交叉連接所有不同值與所有不同值的用戶數月的表,然後左連接的結果表:

SELECT 
    c.ActionBy, m.mon, SUM(h.TimeTakenToComplete) AS TOTAL 
FROM 
    (select distinct ActionBy from myTable) c 
    cross join (select distinct dateadd(month, datediff(month, 0, ActionCreateDate), 0) as mon from myTable) m 
    left outer join myTable h 
    on h.ActionBy=c.ActionBy and dateadd(month, datediff(month, 0, ActionCreateDate), 0)=m.mon 
WHERE 
    TimeTakenToComplete IS NOT NULL 
    AND DeleteDate IS NULL 
    AND ActionBy IS NOT NULL 
GROUP BY 
    c.ActionBy, m.mon 
ORDER BY 
    m.mon ASC 

更換(select distinct ActionBy from myTable)與選擇的用戶表,如果有的話,(select distinct dateadd(month, datediff(month, 0, ActionCreateDate), 0) as mon from myTable)與日曆表上的選擇,如果有的話。