好的,我的标题看起来有点奇怪,但我可以找到一个更好的方法来标题我的问题。
我当前的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 :(得分: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 :(得分: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 on users表(如果有),并将(select distinct dateadd(month, datediff(month, 0, ActionCreateDate), 0) as mon from myTable)
替换为Calendar表上的select(如果有)。
答案 2 :(得分: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
希望这有帮助