繁体   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