SQL Консолидация значений на основе даты и добавление столбца результатов - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть таблица, содержащая следующие данные (дата представляет собой тип данных INT), она состоит из Object с, каждый из которых имеет два Type с, которые могут быть установлены на Not modifiable или Modifiable для определенного временного диапазона:

Object Type StatusOld   StatusNew   Date
/1BCDWB/    2    Not modifiable Modifiable  20011003
HOME    1    Not modifiable Modifiable  20011003
/1BCDWB/    2    Modifiable Not modifiable  20011003
HOME    1    Modifiable Not modifiable  20011003
/0CUST/ 2    Not modifiable Modifiable  20011003
/0SAP/  2    Not modifiable Modifiable  20011003
/0SAP/  2    Modifiable Not modifiable  20011003
/1BCABA/    2    Not modifiable Modifiable  20011003
/1BCABA/    2    Modifiable Not modifiable  20011003
/0CUST/ 2    Not modifiable Modifiable  20011003
/0SAP/  2    Not modifiable Modifiable  20011003
/1BCABA/    2    Not modifiable Modifiable  20011003
/1BCDWB/    2    Not modifiable Modifiable  20011003
/0CUST/ 2    Modifiable Not modifiable  20011003
/0SAP/  2    Modifiable Not modifiable  20011003
/1BCABA/    2    Modifiable Not modifiable  20011003
/1BCDWB/    2    Modifiable Not modifiable  20011003
/0CUST/ 2    Modifiable Not modifiable  20011210
/1BCDWB/    2    Modifiable Not modifiable  20011210
HOME    1    Modifiable Not modifiable  20011210
/0CUST/ 2    Not modifiable Modifiable  20011210
/1BCDWB/    2    Not modifiable Modifiable  20011210
HOME    1    Not modifiable Modifiable  20011210
HOME    1    Not modifiable Modifiable  20020211

, тогда у меня есть таблица с соответствующими временными диапазонами, мне нужно проверить эти значения:

start_date end_date
20000610 20000610
20000611 20011002 

В конечном результате мне нужно просто Yes или No для указанного выше временного диапазона, если для обоих Type 1 и 2 одного Object было установлено значение Modifiable в течение этого времени:

SystemModifiable start_date end_date
No 20000610 20000610
No 20000611 20011002 

Так что я подумал из описания случая CTE:

Case
    When ((Type=1 And StatusNew=Modifiable) And (Type=2 And StatusNew=Modifiable)) And -- For each date range-- Then 'Yes'
    Else 'No'
End As SystemModifiable

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

IF (Type=1 AND StatusNew=modifiable AND
Type=2 AND StatusNew=modifiable) SET SystemModifiable to 'Yes'
ELSE SET SystemModifiable to 'No'

Я ценю вашу помощь, если у вас есть вопросы, дайте мне знать.

Ответы [ 3 ]

1 голос
/ 28 февраля 2020

Попробуйте запрос ниже (комментарии встроены):

select mt.Object, ts.start_date, ts.end_date,
       -- since we have only type 1 or 2, this check will suffice to determine whether 1 and 2 type were included
       case when count(distinct Type) = 2 then 'Yes' else 'No' end
from MyTable mt
right join Timespans ts on mt.Date between ts.start_date and ts.end_date
-- here we want only those records, that were changed to modifiable and only with Type 1 or 2
where mt.Type in (1, 2) and
      mt.StatusNew = 'Modifiable'
      -- to include timespans, which don't have any matching entry
      or (mt.type is null and mt.Object is null)
-- Group by timespan and by object
group by mt.Object, ts.start_date, ts.end_date

Вот демоверсия

ДОПОЛНИТЕЛЬНОЕ ПРИМЕЧАНИЕ Приведенный выше запрос даст вам результаты по временной интервал и для каждого объекта (как вы можете видеть в демонстрации), чтобы получить простой ответ за период, просто снова сгруппируйте, проверяя временной интервал, есть ли Yes в группе:)

0 голосов
/ 28 февраля 2020

Это то, что вы хотите?

select r.start_date, r.end_date, t.object,
       (case when count(distinct type) = 2 then 'Yes' else 'No' end)
from ranges r join
     t
     on t.date between r.start_date and r.end_date
where StatusNew = 'Modifiable' and
      type in (1, 2)
group by t.object;
0 голосов
/ 28 февраля 2020

Я подготовил запрос до вашего последнего изменения - однако, его можно легко изменить, я бы предположил:

Прежде всего я строю cte с временными панелями и всеми используемыми идентификаторами (только в вашем случае 1 и 2). Исходя из этого, я оцениваю последнее изменение статуса выбранного идентификатора за текущий промежуток времени. Исходя из этого, я выполняю операцию поворота, чтобы получить состояние идентификаторов 1 и 2 в одной строке за промежуток времени. Это может быть затем запрошено - как вы упомянули - с помощью case case. Вот пример кода:

WITH cteTimeSpan AS (
  SELECT T3.ID, T2.*, ROW_NUMBER() OVER (ORDER BY start_date) rn
    FROM T2
    CROSS JOIN (SELECT DISTINCT ID FROM T1) AS T3
),
cteStatChanges AS(
  SELECT ts.ID, ts.rn, ts.start_date, ts.end_date, t1.StatusNew, T1.[Date], ROW_NUMBER() OVER (PARTITION BY ts.rn, ts.ID ORDER BY start_date DESC) rn2
    FROM cteTimeSpan AS ts
    LEFT JOIN T1 ON T1.[Date] >= ts.start_date AND T1.[Date] <= ts.end_date
),
cteFilter AS(
  SELECT csc.ID, csc.start_date, csc.end_date, csc.StatusNew
    FROM cteStatChanges csc
    WHERE rn2 = 1
),
ctePiv AS(
  SELECT start_date, end_date, [1], [2]
    FROM cteFilter
  PIVOT (
    MAX(StatusNew)
    FOR ID IN ([1], [2])
  ) piv
)
SELECT p.start_date, p.end_date, CASE WHEN ISNULL([1], N'Not Modifiable') = N'Modifiable' AND ISNULL([2], N'Not Modifiable') = N'Modifiable' THEN N'yes' ELSE N'no' END AS SystemModifiable
  FROM ctePiv p

См. Подробности в скрипте: http://sqlfiddle.com/#! 18 / bf9c5f / 24/1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...