SQL Server查询/查看组合多个数据元素的单行输出

时间:2014-03-12 17:16:00

标签: sql sql-server

考虑SQL Server中的以下两个表:

表#1 - TENDERED

DATE  
DOC_NO
PMNT_SEQ_NO
PAYCODE_TYPE
AMOUNT

--> Primary Key = DATE / DOC_NO / PAYMENT_SEQ_NO

表#2。 TENDERED_CR_CARD

DATE
DOC_NO
PMNT_SEQ_NO
CR_CARD_NO_MASKED
CR_CARD_NAME
CR_CARD_EXP_DATE

-->Primary Key = DATE / DOC_NO / PAYMENT_SEQ_NO

这两个表肯定与其主键值相关。

现在,请考虑这两个表中的以下数据:

DATE        DOC_NO  PMNT_SEQ_NO PAYCODE_TYPE    AMOUNT
03/10/2014  100001     1            CASH            100.00
03/10/2014  100001     2            CASH             -9.75
03/10/2014  100002     1            CASH             50.00
03/10/2014  100002     2            VISA            100.00
03/10/2014  100002     3            VISA            250.00
03/10/2014  100003     1            MC              125.00
03/10/2014  100003     2            AMEX            75.00

DATE        DOC_NO PMNT_SEQ_NO  CR_CARD_MASKED    NAME  CR_CARD_EXP
03/10/2014  100002   2            4225******801289  MARY JONES  2016/08/31
03/10/2014  100002   3            4121******637442  JOHN DOE    2015/04/30
03/10/2014  100003   1            5428******971134  MIKE BAKER  2018/09/30
03/10/2014  100003   2            3732*****344756   LINDA LIU   2017/07/31

好的......所以我们需要的是一个综合的,单一的RECORD审计报告类型查询。生成的查询应根据上面的数据显示下面的电子表格类型格式中表示的SINGLE LINE。注意......在这里指出什么是重要的......只有“现金”和“现实”。投标得到"总结" ...每个单独的信用卡记录必须有自己的字段......如电子表格的相应列中所示(即PMT_TYP_1,AMT_1,PMT_TYP_2,AMT_2等)。

请帮助!任何建议/意见将非常感谢!谢谢!...马克

输出格式:

DATE    DOC_NO  PMNT_TYP_1  AMT_1   CR_CARD_MASK_1  NAME_1  CR_CARD_EXP_1   PMNT_TYP_2  AMT_2   CR_CARD_MASK_2  NAME_2  CR_CARD_EXP_2   PMNT_TYP_3  AMT_3   CR_CARD_MASK_3  NAME_3  CR_CARD_EXP_3

1 个答案:

答案 0 :(得分:0)

这是我对这个问题的解决方案,或者至少是一个很好的起点。

下面注意我有一组标记为CODE BLOCK 1的代码 - 可以将其设置为存储过程,如果在底部的动态SQL中取消注释ALTER VIEW行,则proc可以重新执行建立一个视图。我们目前为报告平台执行此操作,该平台无法调用proc或运行此代码。因此,当新行添加到特定表时,我们有一个触发器触发proc,并自动更改视图。报告平台只需要在那时进行SELECT。注意,由于proc更改,您必须手动创建同名视图(可能是任何模式),然后proc将修复它。

祝你好运!!

IF OBJECT_ID('TEMPDB..#TENDERED') IS NOT NULL
    DROP TABLE #TENDERED
IF OBJECT_ID('TEMPDB..#TENDERED_CD_CARD') IS NOT NULL
    DROP TABLE #TENDERED_CD_CARD

CREATE TABLE #TENDERED (DATE DATETIME, DOC_NO INT, PMNT_SEQ_NO INT, PAYCODE_TYPE NVARCHAR(10), AMOUNT MONEY)
CREATE TABLE #TENDERED_CD_CARD (DATE DATETIME, DOC_NO INT, PMNT_SEQ_NO INT, CR_CARD_NO_MASKED NVARCHAR(16), CR_CARD_NAME NVARCHAR(255), CR_CARD_EXP_DATE NVARCHAR(10))

INSERT INTO #TENDERED
SELECT '03/10/2014',100001,1,'CASH',100.00 UNION ALL
SELECT '03/10/2014',100001,2,'CASH',-9.75 UNION ALL
SELECT '03/10/2014',100002,1,'CASH',50.00 UNION ALL
SELECT '03/10/2014',100002,2,'VISA',100.00 UNION ALL
SELECT '03/10/2014',100002,3,'VISA',250.00 UNION ALL
SELECT '03/10/2014',100003,1,'MC',125.00 UNION ALL
SELECT '03/10/2014',100003,2,'AMEX',75.00

INSERT INTO #TENDERED_CD_CARD
SELECT '03/10/2014',100002,2,'4225******801289','MARY JONES','2016/08/31' UNION ALL
SELECT '03/10/2014',100002,3,'4121******637442','JOHN DOE','2015/04/30' UNION ALL
SELECT '03/10/2014',100003,1,'5428******971134','MIKE BAKER','2018/09/30' UNION ALL
SELECT '03/10/2014',100003,2,'3732*****344756','LINDA LIU','2017/07/31'

/* BEGIN CODE BLOCK 1 */
DECLARE @cols AS NVARCHAR(MAX), 
        @y    AS INT, 
        @sql  AS NVARCHAR(MAX);

DECLARE @COLNAME TABLE (COLNAME NVARCHAR(75), OB INT, PMNT_SEQ_NO INT)

INSERT INTO @COLNAME (COLNAME, OB, PMNT_SEQ_NO)
SELECT DISTINCT 'PAYCODE_TYPE_'+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, 1 AS OB, T.PMNT_SEQ_NO 
FROM #TENDERED T
UNION ALL
SELECT DISTINCT 'AMT_'+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, 2, T.PMNT_SEQ_NO 
FROM #TENDERED T
UNION ALL
SELECT DISTINCT 'CR_CARD_MASK_'+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, 3, T.PMNT_SEQ_NO  
FROM #TENDERED T
JOIN #TENDERED_CD_CARD T2 ON T.DATE=T2.DATE AND T.DOC_NO=T2.DOC_NO AND T.PMNT_SEQ_NO=T2.PMNT_SEQ_NO
UNION ALL
SELECT DISTINCT 'NAME_'+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, 4, T.PMNT_SEQ_NO 
FROM #TENDERED T
JOIN #TENDERED_CD_CARD T2 ON T.DATE=T2.DATE AND T.DOC_NO=T2.DOC_NO AND T.PMNT_SEQ_NO=T2.PMNT_SEQ_NO 
UNION ALL
SELECT DISTINCT 'CR_CARD_EXP_'+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, 5, T.PMNT_SEQ_NO 
FROM #TENDERED T
JOIN #TENDERED_CD_CARD T2 ON T.DATE=T2.DATE AND T.DOC_NO=T2.DOC_NO AND T.PMNT_SEQ_NO=T2.PMNT_SEQ_NO

SET @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT COLNAME AS y, PMNT_SEQ_NO, OB FROM (SELECT COLNAME, PMNT_SEQ_NO, OB FROM @COLNAME ) AS sub
      ) AS Y
ORDER BY PMNT_SEQ_NO, OB
FOR XML PATH('')),
1, 1, N'');

print @cols

SET @sql = N'SELECT *
FROM (SELECT * FROM (SELECT DISTINCT CONVERT(VARCHAR(10), T.DATE, 101) AS DATE, T.DOC_NO, ''PAYCODE_TYPE_''+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, PAYCODE_TYPE AS VAL
                     FROM #TENDERED T
                     UNION ALL
                     SELECT DISTINCT CONVERT(VARCHAR(10), T.DATE, 101) AS DATE, T.DOC_NO, ''AMT_''+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, CAST(AMOUNT AS NVARCHAR) AS VAL
                     FROM #TENDERED T
                     UNION ALL
                     SELECT DISTINCT CONVERT(VARCHAR(10), T.DATE, 101) AS DATE, T.DOC_NO, ''CR_CARD_MASK_''+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, CR_CARD_NO_MASKED AS VAL
                     FROM #TENDERED T
                     JOIN #TENDERED_CD_CARD T2 ON T.DATE=T2.DATE AND T.DOC_NO=T2.DOC_NO AND T.PMNT_SEQ_NO=T2.PMNT_SEQ_NO
                     UNION ALL
                     SELECT DISTINCT CONVERT(VARCHAR(10), T.DATE, 101) AS DATE, T.DOC_NO, ''NAME_''+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, CR_CARD_NAME AS VAL
                     FROM #TENDERED T
                     JOIN #TENDERED_CD_CARD T2 ON T.DATE=T2.DATE AND T.DOC_NO=T2.DOC_NO AND T.PMNT_SEQ_NO=T2.PMNT_SEQ_NO
                     UNION ALL
                     SELECT DISTINCT CONVERT(VARCHAR(10), T.DATE, 101) AS DATE, T.DOC_NO, ''CR_CARD_EXP_''+CAST(T.PMNT_SEQ_NO AS NVARCHAR) AS COLNAME, CR_CARD_EXP_DATE AS VAL
                     FROM #TENDERED T
                     JOIN #TENDERED_CD_CARD T2 ON T.DATE=T2.DATE AND T.DOC_NO=T2.DOC_NO AND T.PMNT_SEQ_NO=T2.PMNT_SEQ_NO
                     ) AS sub) AS D
PIVOT(max(VAL) FOR COLNAME IN(' + @cols + N')) AS P
ORDER BY DATE, DOC_NO;';

--set @sql = N'ALTER VIEW vwMyPaymentSummary as ' + @sql
PRINT @sql
EXEC(@sql)
/* END CODE BLOCK 1 */