多次SQL自连接

多次SQL自连接,sql,sql-server,join,sql-server-2000,Sql,Sql Server,Join,Sql Server 2000,我有一个单独的数据库表来存储周条目 Id Value WeekId 1 1.0000 1 2 2.0000 1 同一周最多可以有三个条目 所以我认为使用自连接可以解决这个问题 SELECT w1.Value, w2.Value, w3.Value FROM [List].[dbo].[testWeekEntries] as w1 LEFT OUTER JOIN [List].[dbo].[testWeekEntries] a

我有一个单独的数据库表来存储周条目

Id        Value     WeekId
1         1.0000    1
2         2.0000    1
同一周最多可以有三个条目

所以我认为使用自连接可以解决这个问题

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
选择w1.Value、w2.Value、w3.Value
从[List].[dbo].[testWeekEntries]开始,作为w1
在w1.WeekId=w2.WeekId上左外连接[List].[dbo].[testWeekEntries]作为w2
在w2.WeekId=w3.WeekId上将[List].[dbo].[testWeekEntries]作为w3左外部联接
其中w1.Id
问题是:最大条目数可以正常工作,但是它不会返回包含一个或两个条目数的行


是否有一种不同类型的联接可以用来回退只有一个或两个条目的行,或者以不同的方式回退?

这些条目不会返回,因为当联接的表返回
NULL
值时,
WHERE
子句会显式地将它们过滤掉

此解决方案向每个记录添加一个连续的行号,每周重新启动为1。这允许您在PIVOT语句中使用此序列号

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

这些条目不会返回,因为当联接的表返回
NULL
值时,
WHERE
子句会显式地将它们过滤掉

此解决方案向每个记录添加一个连续的行号,每周重新启动为1。这允许您在PIVOT语句中使用此序列号

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

您需要在where子句中添加
w2.Id为null
w3.Id为null

大概是

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)
在哪里
(w2.Id为null,w3.Id为null)或
(w3.id为空且w1.id
您需要在where子句中添加
w2.Id为空的可能性
w3.Id为空的可能性

大概是

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)
在哪里
(w2.Id为null,w3.Id为null)或
(w3.id为空且w1.id
您也可以使用
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

您也可以使用
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

我尝试了这个方法,但是现在它会返回多行,而每周只能返回一行Id@user900566-你是对的,我错了。你在用什么数据库管理系统?@user900566-我已经调整了答案来解决这个错误。@user900566-老实说,我有一种烦人的感觉,它可以简化,但我似乎无法实现。我刚刚意识到productino服务器是ms sql 2000,没有行号()功能性我尝试过这个,但是现在它会返回多行,每周只能返回一行Id@user900566-你是对的,我错了。你在用什么数据库管理系统?@user900566-我已经调整了答案来解决这个错误。@user900566-老实说,我有一种烦人的感觉,它可以简化,但我似乎无法实现。我刚刚意识到productino服务器是ms sql 2000,没有行数()功能+1 Thx Martin,PIVOT仍然不是我的拿手好戏,但我不得不问:如果不使用CTE并添加行数,是否有更简单的解决方案。@Lieven-我想不出来!你不知道这对我来说有多安慰。+1 Thx马丁,PIVOT仍然不是我喜欢的,但我不得不问:如果不使用CTE并添加行数,是否有更简单的解决方案。@Lieven-我想不出来!你不知道这对我有多安慰。