Есть ли оптимальный способ создания логических столбцов из физического столбца с помощью оператора SQL-запроса? - PullRequest
0 голосов
/ 26 марта 2019

Я пишу SQL-запрос, используя таблицу. Мое требование - мне нужно создать два логических столбца из одного физического столбца с определенными условиями. В SQL, как сгенерировать два логических столбца в окончательном наборе результатов?

До сих пор я пытался использовать подзапросы для получения этих логических столбцов. Но этот подзапрос возвращает ошибку при включении его в качестве столбца в основной запрос.

В целом есть другие таблицы, которые будут объединены с использованием SQL JOIN для получения соответствующих столбцов.

Колонки:

  1. CarrierName NVARCHAR(10)
  2. MonthDate DATETIME
  3. Stage INT

Сценарий:
В моей таблице SQL Server есть столбец с именем Stage типа int, который содержит значения, такие как 1, 2, 3, 4.

Теперь у меня есть два критерия даты, которые нужно применить к столбцу выше, чтобы получить два логических столбца в окончательном наборе результатов.

Критерии № 1:

Получите носителей с прошлых 12 месяцев и априорных значений до даты окончания прошлого месяца, и значение «CurrentStage» должно быть меньше, чем и получить «PriorStage»

Пример:

Текущий месяц: март 2019 (2019-03-25) или любая другая дата Последняя дата окончания последнего месяца будет: 2019-02-28

12 месяцев до предыдущего прошлого месяца будет: С 2018-02-01 по 2019-01-31

Критерии № 2:

Получите носителей с даты последнего последнего месяца и получите "CurrentStage"

При написании двух независимых операторов SQL SELECT я получаю желаемые результаты. Моя проблема заключается в том, когда я думаю, что они объединяются в одном утверждении выбора.

Я получаю эту ошибку:

Подзапрос вернул более 1 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения

Код:

DECLARE @DATE DATETIME
SET @DATE = '2018-08-25';

--QUERY 1 - RECORDS WITH PREVIOUS MONTH END DATE
SELECT 
    T1.CarrierName AS 'Carrier_Number', 
    T1.Stage AS 'Monitoring_Stage–Current'
FROM 
    table1 T1
WHERE 
    T1.Stage IS NOT NULL AND 
    CONVERT(DATE, T1.MonthDate) = CONVERT(DATE, DATEADD(D, -(DAY(@DATE)), @DATE)) 

--QUERY 2 - RECORDS FROM PAST 12 MONTHS PRIOR PREVIOUS MONTH END DATE
SELECT 
    T2.CarrierName,
    T2.Stage AS 'Monitoring_Stage–Prior'
FROM
    table2 T2
WHERE 
    T2.Stage IS NOT NULL AND 
    CONVERT(DATE, T2.MonthDate) BETWEEN CONVERT(DATE, DATEADD(M, -12, DATEADD(D, -(DAY(@DATE)), @DATE)))                         
                                    AND CONVERT(DATE, DATEADD(D, -(DAY(@DATE) + (DAY(DATEADD(D, -(DAY(@DATE)), @DATE)))), @DATE)) 
    AND T2.Stage) > (SELECT DISTINCT MAX(m.Stage AS INT))
                     FROM table1 m                                
                     WHERE CONVERT(DATE, m.MonthDate) = CONVERT(DATE, DATEADD(D, -(DAY(@DATE)), @DATE)) 
                       AND T2.CarrierName = m.CarrierName)

Мой окончательный ожидаемый набор результатов должен содержать столбцы ниже. Где значение CurrentStage меньше значения PriorStage.

Ожидаемые результаты

CarrierName   | CurrentStage | PriorStage
--------------+--------------+-------------
C11122        | 1            | 2
C32233        | 3            | 4

Фактический результат

Я ищу альтернативы. То есть CTE, Union, временная таблица и т. Д.

Что-то вроде:

SELECT 
    CarrierName,
    Query 1 Result As 'CurrentStage',
    Query 2 Result As 'PrioreStage'
FROM
    table1

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

Решение:

SELECT 
    DISTINCT M.CarrierName, A.[CurrentStage], B.[PriorStage] 
    FROM
    --QUERY 1 - RECORDS WITH CURRENT MONTH END DATE
(SELECT M.CarrierName, M.CarrierID
    , Stage AS 'CurrentStage'
    FROM table1 M 
    WHERE M.Stage IS NOT NULL AND 
    CONVERT(date, M.MonthDate) = CONVERT(date, DATEADD(D,-(DAY(@DATE)), @DATE)) 
) 
A **inner join**
(
--QUERY 2 - RECORDS FROM PAST 12 MONTHS PRIOR CURRENT MONTH END DATE
SELECT M2.CarrierName, M2.CarrierID
    , Stage AS 'PriorStage'
    FROM table1 M2
    WHERE M2.Stage IS NOT NULL AND 
    CONVERT(date, M2.MonthDate) BETWEEN CONVERT(date, DATEADD(M, -12, DATEADD(D,-(DAY(@DATE)), @DATE))) 
                                            AND CONVERT(date, DATEADD(D,-(DAY(@DATE)+(DAY(DATEADD(D,-(DAY(@DATE)), @DATE)))), @DATE)) 
    AND M2.Stage > (SELECT DISTINCT max(m.Stage)
                                                  FROM table1 m
                                                  WHERE CONVERT(date, m.MonthDate) = CONVERT(date, DATEADD(D,-(DAY(@DATE)), @DATE)) AND
                                                  M2.CarrierName = m.CarrierName
                                                 )

) B on b.Carrier_Number = a.Carrier_Number
INNER JOIN table1 M ON A.CarrierID = M.CarrierID AND B.CarrierID = M.CarrierID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...