Генерация производной таблицы в SSRS из последних покупок в двух разных таблицах SQL Server, а затем соединение с третьей - PullRequest
0 голосов
/ 13 октября 2018

Предположим, у меня есть три таблицы:

  • одна информация о клиенте с уникальным идентификатором (CUST_ID)
  • одна из клиентских штанов покупает 3 столбца (CUST_ID, PANT_TYPE, PANT_DATE)
  • одна из рубашек клиента приобретает 3 колонки (CUST_ID, SHIRT_TYPE, SHIRT_DATE)

Кроме того, я хочу исключить определенные типы брюк и определенные типы рубашек (PANT_TYPE НЕ 'JEANS', SHIRT_TYPE НЕ НУЖНО'TUXEDO'), и захватите только самую последнюю покупку брюк и рубашку.

Итак, в идеале я бы закончил с таким финальным столом:

CUST_ID, LAST_PANT_TYPE, LAST_PANT_DATE, LAST_SHIRT_TYPE, LAST_SHIRT_DATE

В течение четырех часов вработа Я пытался заставить это решение работать , но оператор 'OVER' нарушает SSRS и вызывает проблемы при тестировании запроса и даже время от времени отбрасывает поля случайным образом.Итак, я думаю, что производные таблицы могут работать.

Я довольно новичок в SQL и многому научился, пытаясь решить эту проблему, но мне нужно получить STAT.

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

В итоге я сделал данные и использовал ROW_NUMBER для определения последней покупки.

SELECT 1 AS CUST_ID
INTO #CUSTOMERS 
UNION 
SELECT 2
UNION 
SELECT 3
UNION 
SELECT 4

SELECT 1 AS CUST_ID, 'SLACKS' AS PANT_TYPE, CAST('1/1/2017' AS DATE) AS PANT_DATE
INTO #PANTS
UNION
SELECT 1, 'CARGO SHORTS', CAST('2/2/2018' AS DATE)
UNION
SELECT 1, 'SLACKS', CAST('3/3/2018' AS DATE)
UNION
SELECT 2, 'CARGO PANTS', CAST('2/2/2017' AS DATE)
UNION
SELECT 2, 'SLACKS', CAST('4/4/2018' AS DATE)
UNION
SELECT 3, 'CARGO PANTS', CAST('4/1/2018' AS DATE)
UNION
SELECT 3, 'SLACKS', CAST('5/8/2017' AS DATE)
UNION
SELECT 4, 'CARGO SHORTS', CAST('2/2/2018' AS DATE)
UNION
SELECT 4, 'SLACKS', CAST('3/3/2018' AS DATE)
UNION
SELECT 4, 'CARGO PANTS', CAST('2/2/2017' AS DATE)
UNION
SELECT 4, 'SLACKS', CAST('4/4/2018' AS DATE)
UNION
SELECT 4, 'CARGO PANTS', CAST('4/1/2018' AS DATE)
UNION
SELECT 4, 'SLACKS', CAST('5/8/2017' AS DATE)

SELECT 1 AS CUST_ID, 'POLO' AS SHIRT_TYPE, CAST('1/1/2017' AS DATE) AS SHIRT_DATE
INTO #SHIRTS
UNION
SELECT 1, 'POLO - LONG SLEEVE', CAST('2/2/2018' AS DATE)
UNION
SELECT 1, 'POLO - LONG SLEEVE', CAST('3/3/2018' AS DATE)
UNION
SELECT 2, 'POLO', CAST('2/2/2017' AS DATE)
UNION
SELECT 2, 'POLO - LONG SLEEVE', CAST('4/4/2018' AS DATE)
UNION
SELECT 3, 'T-SHIRT', CAST('4/1/2018' AS DATE)
UNION
SELECT 3, 'POLO', CAST('5/8/2017' AS DATE)
UNION
SELECT 4, 'T-SHIRT', CAST('2/2/2018' AS DATE)
UNION
SELECT 4, 'POLO', CAST('3/3/2018' AS DATE)
UNION
SELECT 4, 'T-SHIRT', CAST('2/2/2017' AS DATE)
UNION
SELECT 4, 'POLO - LONG SLEEVE', CAST('4/4/2018' AS DATE)
UNION
SELECT 4, 'T-SHIRT', CAST('4/1/2018' AS DATE)
UNION
SELECT 4, 'POLO', CAST('5/8/2017' AS DATE)

SELECT C.CUST_ID, P.PANT_TYPE, P.PANT_DATE, 
    S.SHIRT_TYPE, S.SHIRT_DATE
FROM #CUSTOMERS C
LEFT JOIN (SELECT CUST_ID, PANT_TYPE, PANT_DATE, ROW_NUMBER()OVER(PARTITION BY CUST_ID ORDER BY PANT_DATE DESC) AS ROW_NUM FROM #PANTS) P ON P.CUST_ID = C.CUST_ID AND P.ROW_NUM = 1 
LEFT JOIN (SELECT CUST_ID, SHIRT_TYPE, SHIRT_DATE, ROW_NUMBER()OVER(PARTITION BY CUST_ID ORDER BY SHIRT_DATE DESC) AS ROW_NUM FROM #SHIRTS) S ON S.CUST_ID = C.CUST_ID AND S.ROW_NUM = 1  
0 голосов
/ 13 октября 2018

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

WITH
  p (cust_id, pant_type, pant_date, rn) AS (
    SELECT cust_id, pant_type, pant_date,
      ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY pant_date DESC)
    FROM Pants WHERE pant_type NOT IN ('JEANS')
  ),
  s (cust_id, shirt_type, shirt_date, rn) AS (
    SELECT cust_id, shirt_type, shirt_date,
      ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY shirt_date DESC)
      FROM Shirts WHERE shirt_type NOT IN ('TUXEDO')
  )
SELECT c.cust_id, 
  p.pant_type AS last_pant_type, p.pant_date AS last_pant_date,
  s.shirt_type AS last_shirt_type, s.shirt_date AS last_shirt_date
FROM Customers c
  LEFT JOIN p ON c.cust_id = p.cust_id AND p.rn = 1
  LEFT JOIN s ON c.cust_id = s.cust_id AND s.rn = 1;
0 голосов
/ 13 октября 2018

Вы можете попробовать использовать оператор APPLY, например:

SELECT
    C.CUST_ID
    , PANT.PANT_TYPE LAST_PANT_TYPE
    , PANT.PANT_DATE LAST_PANT_DATE
    , SHIRT.SHIRT_TYPE LAST_SHIRT_TYPE
    , SHIRT.SHIRT_DATE LAST_SHIRT_DATE
FROM
    CUSTOMER C
    OUTER APPLY
    (
        SELECT TOP 1
            P.PANT_TYPE
            , P.PANT_DATE
        FROM PANT P
        WHERE
            P.CUST_ID = C.CUST_ID
            AND P.PANT_TYPE <> 'JEANS'
        ORDER BY P.PANT_DATE DESC
    ) PANT
    OUTER APPLY
    (
        SELECT TOP 1
            S.SHIRT_TYPE
            , S.SHIRT_DATE
        FROM SHIRT S
        WHERE
            S.CUST_ID = C.CUST_ID
            AND S.SHIRT_TYPE <> 'TUXEDO'
        ORDER BY S.SHIRT_DATE DESC
    ) SHIRT

Использование OUTER APPLY (в отличие от CROSS APPLY) гарантирует, что ни один из клиентов не будет отфильтрован (NULLбудет возвращено в столбцах «PANT» или «SHIRT», если в соответствующих таблицах нет данных для клиента).

...