我有一个包含按年和周的数据的表格。我想从该表中选择年份和月份子集中的所有内容,以及在找不到该周/年组合的地方使用默认值的行。
这是一个测试脚本:
--create test table and insert data
CREATE TABLE [dbo].[TestPD](
[id] [int] NOT NULL,
[year] [int] NOT NULL,
[week] [int] NOT NULL,
[name] [varchar](50) NOT NULL,
[item] [int] NOT NULL,
) ON [PRIMARY]
GO
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (1, 2013, 15, N'bob', 5)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (1, 2014, 15, N'bob', 4)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (2, 2013, 15, N'joe', 3)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (3, 2014, 15, N'rick', 2)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (1, 2012, 15, N'rick', 1)
GO
--LookupDates contains the year/week combos to extract from the table
WITH LookupDates AS (
SELECT DATEPART(YEAR, GETDATE()) AS [LookupYear], DATEPART(WEEK, GETDATE()) as [LookupWeek]
UNION
SELECT DATEPART(YEAR, GETDATE()) - 1, DATEPART(WEEK, GETDATE())
)
--what I tried (doesn't return "blank" rows)
SELECT t1.[LookupYear], t1.[LookupWeek], ISNULL(id, 0), ISNULL(Name, 'not found'), ISNULL(item, 0)
FROM LookupDates as t1 LEFT JOIN TESTPD as t2 on t1.LookupYear = t2.[year] and t1.LookupWeek = t2.[Week]
我喜欢的是看起来像这样的数据(每个id /年/月的一行)组合,无论它是否存在于TestPD
表中:(具有0值的行) item
实际上并不存在,只是添加了默认值。
id year week name item ----------- ----------- ----------- --------- ----------- 1 2013 1 bob 5 1 2014 1 bob 4 2 2013 1 joe 3 2 2014 1 joe 0 3 2013 1 rick 0 3 2014 1 rick 2
我怎样才能做到这一点?我不必使用CTE,我只是认为这是保存我需要数据的年/周的最佳方式。
答案 0 :(得分:1)
以下评论编辑。
您需要与ID交叉加入才能获得所需内容。这是一种方法,但这是他们的关键。
--create test table and insert data
CREATE TABLE [dbo].[TestPD](
[id] [int] NOT NULL,
[year] [int] NOT NULL,
[week] [int] NOT NULL,
[name] [varchar](50) NOT NULL,
[item] [int] NOT NULL,
) ON [PRIMARY]
GO
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (1, 2013, 15, N'bob', 5)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (1, 2014, 15, N'bob', 4)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (2, 2013, 15, N'joe', 3)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (3, 2014, 15, N'rick', 2)
INSERT [dbo].[TestPD] ([id], [year], [week], [name], [item]) VALUES (1, 2012, 15, N'rick', 1)
GO
--LookupDates contains the year/week combos to extract from the table
;WITH LookupDates AS (
SELECT DATEPART(YEAR, GETDATE()) AS [LookupYear], DATEPART(WEEK, GETDATE()) as [LookupWeek]
UNION
SELECT DATEPART(YEAR, GETDATE()) - 1, DATEPART(WEEK, GETDATE())
)
,UserDates AS (
SELECT *
FROM LookupDates
CROSS JOIN
(SELECT id FROM TESTPD GROUP BY id) a
)
SELECT t1.LookupYear
, t1.LookupWeek
, ISNULL(t2.id, 0) id
, ISNULL(Name, 'not found') Name
, ISNULL(item, 0) Item
FROM UserDates as t1
LEFT JOIN
TESTPD as t2 on t1.LookupYear = t2.[year]
and t1.LookupWeek = t2.[Week]
and t1.id = t2.id
LookupYear LookupWeek id Name Item
----------- ----------- ----------- -------------------------------------------------- -----------
2013 15 1 bob 5
2013 15 2 joe 3
2013 15 0 not found 0
2014 15 1 bob 4
2014 15 0 not found 0
2014 15 3 rick 2
答案 1 :(得分:0)
WITH LookupDates AS (
SELECT DATEPART(YEAR, GETDATE()) AS [LookupYear], DATEPART(WEEK, GETDATE()) as [LookupWeek]
UNION
SELECT DATEPART(YEAR, GETDATE()) - 1, DATEPART(WEEK, GETDATE())
)
--this will return "blank" rows
SELECT t1.[LookupYear], t1.[LookupWeek], id, Name, item
FROM LookupDates as t1
JOIN TESTPD as t2 on t1.LookupYear = t2.[year] and t1.LookupWeek = t2.[Week]
UNION ALL
SELECT t1.[LookupYear], t1.[LookupWeek], id, 'Not Found', item
FROM LookupDates AS t1
CROSS JOIN TESTPD AS t2
WHERE NOT EXISTS (SELECT 1
FROM TESTPD t3
WHERE t3.ID = T2.ID
AND t3.item = T2.item
AND t3.[year] = t1.[LookupYear]
and t3.[Week] = t1.[LookupWeek])
ORDER BY 1, 2, 3, 4