#sql #sql-server #sql-server-2012
#sql #sql-server #sql-server-2012
Вопрос:
Мне сложно сформулировать этот вопрос.
У меня есть таблица, как показано ниже:
Дата | ItemNumber | FlagA | ФлагB |
---|---|---|---|
2020-01-01 | 101 | Y | N |
2020-01-02 | 101 | N | N |
2020-01-03 | 101 | Y | N |
2020-01-04 | 101 | Y | N |
2020-01-05 | 101 | Y | Y |
2020-01-01 | 102 | Y | N |
2020-01-02 | 102 | N | N |
2020-01-03 | 102 | N | N |
2020-01-04 | 102 | Y | Y |
Моя цель — подсчитать последовательные даты, где FlagA = Y, включая и предшествующие дате, где flagB = Y для каждого ItemNumber . Последняя дата для каждого ItemNumber в таблице всегда будет иметь flagB = Y.
Я пытаюсь добиться этого, добавив дополнительный столбец:
Дата | ItemNumber | FlagA | ФлагB | RunningCount |
---|---|---|---|---|
2020-01-01 | 101 | Y | N | 0 |
2020-01-02 | 101 | N | N | 0 |
2020-01-03 | 101 | Y | N | 1 |
2020-01-04 | 101 | Y | N | 2 |
2020-01-05 | 101 | Y | Y | 3 |
2020-01-01 | 102 | Y | N | 0 |
2020-01-02 | 102 | N | N | 0 |
2020-01-03 | 102 | N | N | 0 |
2020-01-04 | 102 | Y | Y | 1 |
Я работаю на SQL Server 2012, но не имею большого опыта работы с оконными функциями. Я пробовал несколько вещей, в том числе:
COUNT(CASE WHEN [FLagB] = 'Y' THEN 1 ELSE 0 END)
over (partition by [ItemNumber],[FlagB]
order by [Date] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [RunningCount]
и:
COUNT(CASE WHEN [FLagB] = 'Y' THEN [ItemNumber] END)
over (PARTITION BY [ItemNumber]
order by [Date] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [RunningCount]
но они не получили правильных результатов.
Возможно, есть лучший способ сделать это — мне не нужно добавлять новый столбец в таблицу, мне нужен только запрос, который предоставляет количество для каждого ItemNumber .
Любые советы будут с благодарностью приняты. Заранее благодарю вас.
Ответ №1:
Похоже, вам нужно перечисление flagA = Y
для самой последней непрерывной последовательности. Это было бы:
select t.*,
(case when grp = 0 and flagA = 'Y'
then row_number() over (partition by grp, flagA order by date)
else 0
end) as runningCount
from (select t.*,
sum(case when flagA = 'N' then 1 else 0 end) over (partition by itemNumber order by date desc) as grp
from t
) t;
Комментарии:
1. Спасибо за ответ, к сожалению, у меня это не сработало. При попытке присвоить псевдоним части инструкции case как ‘seqnum’ выдается ошибка. Удаление этого добавляет счетчик, начинающийся с 1 для первой даты первого номера элемента по последнюю дату, затем возвращает 0 для остальных номеров элементов и дат.
2. @sprVUHL . , , я удалил это.