[英]SQL self join multiple times
I have a single database table that stores week entries. 我有一个存储星期条目的数据库表。
Id Value WeekId
1 1.0000 1
2 2.0000 1
There can be up to three entries with the same week. 同一星期最多可以有三个条目。
So I figured using a self join would solve this 所以我想使用自我联接可以解决这个问题
SELECT w1.Value, w2.Value, w3.Value
FROM [List].[dbo].[testWeekEntries] as w1
LEFT OUTER JOIN [List].[dbo].[testWeekEntries] as w2 ON w1.WeekId = w2.weekId
LEFT OUTER JOIN [List].[dbo].[testWeekEntries] as w3 ON w2.WeekId = w3.WeekId
WHERE w1.Id < w2.Id AND w2.Id < w3.Id
The problem: It worls fine with the maximum number of entries however it doesn't pull back a row with one or two entries. 问题:使用最大条目数时,它会很糟糕,但是不会回退包含一两个条目的行。
Is there a different type of join I can use to pull back a row with only one or two entries or a different way of approaching this? 我是否可以使用其他类型的联接来拉回仅包含一个或两个条目的行,或者采用不同的方式来实现这一点?
These entries are not returning because your WHERE
clause explicitly filters them out when the joined tables return NULL
values. 这些条目不会返回,因为当联接的表返回
NULL
值时,您的WHERE
子句会明确过滤掉它们。
This solution adds a sequential rownumber to each record, restarting to 1 for each week. 此解决方案向每个记录添加一个连续的行号,然后每周重新开始为1。 This allows you to use this sequential number in a PIVOT statement
这使您可以在PIVOT语句中使用此序列号
SQL 2000 Statement SQL 2000语句
SELECT *
FROM (
SELECT (SELECT COUNT(*)
FROM testWeekEntries
WHERE Id <= we.Id
AND WeekId = we.WeekId) as rn
, Value
, WeekId
FROM testWeekEntries we
) q
PIVOT (MAX(Value) FOR rn IN ([1],[2],[3]) ) AS PVT
SQL 2008 Statement SQL 2008语句
;WITH q AS (
SELECT rn = ROW_NUMBER() OVER (PARTITION BY WeekId ORDER BY Id)
, Id
, Value
, WeekId
FROM [testWeekEntries] as w1
)
SELECT Value
, (SELECT Value FROM q q1 WHERE q1.rn = q.rn + 1 AND q1.WeekId = q.WeekId)
, (SELECT Value FROM q q2 WHERE q2.rn = q.rn + 2 AND q2.WeekId = q.WeekId)
FROM q
WHERE q.rn = 1
You will need to add in your where clause the possibility that w2.Id is null
or w3.id is null
您将需要在where子句中添加
w2.Id is null
或w3.id is null
的可能性
So something like 所以像
WHERE
(w2.Id is null and w3.id is null) or
(w3.id is null and w1.id < w2.id) or
(w1.id < w2.id and w2.id < w3.id)
You can also use PIVOT
您也可以使用
PIVOT
;WITH CTE AS
(
SELECT Value,
WeekId,
ROW_NUMBER() OVER (PARTITION BY WeekId ORDER BY Id) AS RN
FROM [List].[dbo].[testWeekEntries]
)
SELECT *
FROM CTE
PIVOT (MAX(Value) FOR RN IN ([1],[2],[3]) ) AS PVT
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.