SQL для получения списка дат, а также дней до и после без дубликатов - PullRequest
3 голосов
/ 11 марта 2010

Мне нужно отобразить список дат, который у меня есть в таблице

SELECT mydate AS MyDate, 1 AS DateType
FROM myTable
WHERE myTable.fkId = @MyFkId;

1 января 2010 г. - 1
2 января 2010 г. - 1
10 января 2010 г. - 1

Нет проблем. Однако теперь мне нужно отобразить дату до и дату после с другим типом DateType.

31 декабря 2009 г. - 2
1 января 2010 г. - 1
2 января 2010 г. - 1
3 января 2010 г. - 2
9 января 2010 г. - 2
10 января 2010 г. - 1
11 января 2010 г. - 2

Я думал, что смогу использовать союз

SELECT MyDate, DateType
FROM (
    SELECT mydate - 1 AS MyDate, 2 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;

    UNION

    SELECT mydate + 1 AS MyDate, 2 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;

    UNION

    SELECT mydate AS MyDate, 1 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;
) AS myCombinedDateTable

Сюда, однако, входят дубликаты оригинальных дат.

31 декабря 2009 г. - 2
1 января 2010 г. - 2
1 января 2010 г. - 1
2 января 2010 г. - 2
2 января 2010 г. - 1
3 января 2010 г. - 2
9 января 2010 г. - 2
10 января 2010 г. - 1
11 января 2010 г. - 2

Как мне лучше всего удалить эти дубликаты? Я рассматриваю временную таблицу, но не уверен, что это лучший способ сделать это.

Мне также кажется, что это может привести к проблемам с производительностью, поскольку я выполняю один и тот же запрос три раза подряд.

Как лучше всего обработать этот запрос?

Ответы [ 3 ]

4 голосов
/ 11 марта 2010

Это должно работать для вас:

SELECT MyDate, min(DateType) as DateType
FROM (
    SELECT mydate - 1 AS MyDate, 2 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;

    UNION

    SELECT mydate + 1 AS MyDate, 2 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;

    UNION ALL

    SELECT mydate AS MyDate, 1 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId;
) AS myCombinedDateTable
group by MyDate

Примечание: я изменил второй UNION на UNION ALL для лучшей производительности; последний подзапрос никогда не будет иметь дубликатов с первыми двумя подзапросами, поскольку DateType всегда равно 2 для первых двух и 1 для последнего UNION редактируемого запроса.

1 голос
/ 11 марта 2010

Хотя вы приняли решение, позвольте мне дать это решение для справки:

SELECT MyDate, Min(DateType)
From
(
  SELECT MyDate + T1.RecordType AS MyDate, T1.DateType
  FROM
  (
    Select 1 AS RecordType, 2 AS DateType
    Union ALL
    Select 0 AS RecordType, 1 AS DateType
    Union ALL
    Select -1 AS RecordType, 2 AS DateType
  ) AS T1
  CROSS JOIN myTable
  Where myTable.fkId = @MyFkId
) AS CombinedTable
Group By MyDate

Преимущество этого решения, myTable запрашивается только один раз, в текущем случае у нас есть фильтр по fkID, поэтому сейчас производительность не будет иметь значения, но если нам придется оценивать сложный запрос, тогда этот метод может работать нормально в отношении Union.

0 голосов
/ 11 марта 2010

Попробовал это, и это работает. Обратите внимание, что я использовал DATEADD для работы с моей локальной копией SQL, SQL2008.

SELECT MyDate, Min(DateType)
FROM (
    SELECT DATEADD(DAY,-1,mydate) AS MyDate, 2 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId

    UNION

    SELECT DATEADD(DAY,1,mydate) as MyDate, 2 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId

    UNION

    SELECT mydate AS MyDate, 1 AS DateType
    FROM myTable
    WHERE myTable.fkId = @MyFkId
) AS myCombinedDateTable
group by Mydate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...