SQL сам присоединяется несколько раз - PullRequest
1 голос
/ 15 января 2012

У меня есть одна таблица базы данных, в которой хранятся записи недели.

Id        Value     WeekId
1         1.0000    1
2         2.0000    1

Может быть до трех записей за одну неделю.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

Проблема: она работает нормально с максимальным количеством записей, но не возвращает строку с одной или двумя записями.

Существует ли другой тип соединенияЯ могу использовать для возврата строки только с одной или двумя записями или другим способом приблизиться к этому?

Ответы [ 3 ]

2 голосов
/ 15 января 2012

Эти записи не возвращаются, потому что ваше предложение WHERE явно отфильтровывает их, когда объединенные таблицы возвращают значения NULL.

Это решение добавляет последовательное количество строк к каждой записи, перезапуская до 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

Оператор 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
1 голос
/ 15 января 2012

Вы также можете использовать 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
1 голос
/ 15 января 2012

Вам нужно будет добавить в ваше предложение where возможность того, что w2.Id is null или w3.id is 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)
...