CTE по идентификатору, статусу и дате приводит к тому, что результаты становятся квадратными - PullRequest
0 голосов
/ 07 марта 2011

У меня есть таблица, определенная как

CREATE TABLE ItemDetail (
    ItemNumber        bigint not null,
    SiteId            int not null,
    Status            int not null,
    ScanDate          datetime not null,
)

Что я пытаюсь сделать, так это получить счет по сайту, по статусу, по дням.У меня есть CTE, как определено

;WITH statCTE AS (
    SELECT
        Count(ItemNumber) over(partition by SiteId, Status, DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate))) as ItemCount,
        SiteId,
        Status,
        DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate)) AS ScanDate
    FROM
        ItemDetail
)

Проблема заключается в том, что когда я запускаю

select * from statCTE where siteid = 119 and scandate = '3/3/2011'

, я получаю

ItemCount SiteId Status ScanDate
2   119 0   2011-03-03 00:00:00.000
2   119 0   2011-03-03 00:00:00.000
6   119 5   2011-03-03 00:00:00.000
6   119 5   2011-03-03 00:00:00.000
6   119 5   2011-03-03 00:00:00.000
6   119 5   2011-03-03 00:00:00.000
6   119 5   2011-03-03 00:00:00.000
6   119 5   2011-03-03 00:00:00.000

Результирующий набор должен состоять из 2 строкодин с 2 для статуса 0 и один с 6 для статуса 6. Итак, мой раздел не работает с преобразованием даты в просто объект даты и выбором результатов.Я мог бы просто получить квадратный корень из сумм ItemCount в моем последнем запросе (сводная таблица), но это скорее хак, чем исправление реальной проблемы.

1 Ответ

2 голосов
/ 07 марта 2011

Вы неправильно понимаете использование оконных функций (или функций ранжирования). В вашем случае Count НЕ является совокупностью. Это использование добавляет результат функции в КАЖДУЮ строку, возвращаемую запросом. Обычно агрегат обрабатывается ДО предложения select, однако в этом примере он обрабатывает предложение ALONG select. Таким образом, TSQL подсчитывает, сколько строк удовлетворяет вашему разделу, и выводит его по КАЖДОЙ строке, возвращаемой запросом.

У вас есть 2 раздела с порядковым счетом 2 и 6 (рассчитывается с помощью функции разделения окна), а затем весь набор результатов добавляется с дополнительным столбцом.

Если вам нужны результаты 2 и 6, вам нужно написать запрос, используя выражение group by

WITH statCTE AS (
    SELECT
        Count(ItemNumber)as ItemCount,
        SiteId,
        Status,
        DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate)) AS ScanDate
    FROM
        ItemDetail
    group by  SiteId, Status, DATEADD(dd, 0, DATEDIFF(dd, 0, ScanDate))
)
...