簡體   English   中英

從最后購買的兩個不同的SQL Server表中生成SSRS中的派生表,然后與第三個表連接

[英]Generating a derived table in SSRS from last purchases in two different SQL Server tables, and then joining with a third

假設我有三個表:

  • 具有唯一ID( 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。

您可以嘗試使用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相對)可確保不會過濾掉任何客戶(如果在各自的表中沒有針對客戶的數據,則將在“ PANT”或“ SHIRT”列中返回NULL )。

對派生表使用通用表表達式 ,查詢看起來像這樣:

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;

我最終制作了數據,並使用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  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM