简体   繁体   English

SQL自连接多次

[英]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 nullw3.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM