将多个记录分组为单行

时间:2013-10-20 05:52:02

标签: sql sql-server tsql

给出以下查询:

SELECT  C.AGENCY_NAME, B.PROJECT_NUMBER, B.PROJECT_NAME, D.CONTRACT_NO, 
            B.PROJECT_START_DATE,
            CASE WHEN E.CHECK_AMOUNT IS NOT NULL AND A.MONTH = 'JUL' THEN
                F.NAME + ' ' + CONVERT(VARCHAR(10), CHECK_DATE, 101) + ' ' + CASE WHEN CONVERT(VARCHAR(10), CHECK_NUMBER) IS NOT NULL THEN 'CHK# ' END 
                + CONVERT(VARCHAR(10), CHECK_NUMBER) ELSE /*START CODE IF PEOPLESOFT DATA DOESN'T EXIST*/
                (SELECT TOP 1 CASE WHEN STATUS = 1 THEN 'Approved-' WHEN STATUS = 3 THEN 'Hold-' ELSE 'Rejected-' END
                    + WORKFLOW_NAME + '-' + CONVERT(VARCHAR(10), DATE, 101) FROM FINANCE_WORKFLOW_DETAILS G, FINANCE_WORKFLOW H 
                    WHERE G.WORKKFLOW_ID_STATE = H.FINANCE_WORKFLOW_ID AND G.INVOICE_ID = A.INVOICE_NUMBER AND A.PROGRAM_ID = G.PROGRAM_ID
                    AND (A.MONTH = 'JUL') ORDER BY DATE DESC) END 'July',

            CASE WHEN E.CHECK_AMOUNT IS NOT NULL AND A.MONTH = 'AUG' THEN
                F.NAME + ' ' + CONVERT(VARCHAR(10), CHECK_DATE, 101) + ' ' + CASE WHEN CONVERT(VARCHAR(10), CHECK_NUMBER) IS NOT NULL THEN 'CHK# ' END 
                + CONVERT(VARCHAR(10), CHECK_NUMBER) ELSE /*START CODE IF PEOPLESOFT DATA DOESN'T EXIST*/
                (SELECT TOP 1 CASE WHEN STATUS = 1 THEN 'Approved-' WHEN STATUS = 3 THEN 'Hold-' ELSE 'Rejected-' END
                    + WORKFLOW_NAME + '-' + CONVERT(VARCHAR(10), DATE, 101) FROM FINANCE_WORKFLOW_DETAILS G, FINANCE_WORKFLOW H 
                    WHERE G.WORKKFLOW_ID_STATE = H.FINANCE_WORKFLOW_ID AND G.INVOICE_ID = A.INVOICE_NUMBER AND A.PROGRAM_ID = G.PROGRAM_ID
                    AND A.MONTH = 'AUG' ORDER BY DATE DESC) END 'August'

        FROM EXPENSES A
        INNER JOIN PROGRAMS B ON A.PROGRAM_ID = B.PROGRAM_ID
        INNER JOIN AGENCIES C ON B.AGENCY_ID = C.AGENCY_ID
        INNER JOIN CONTRACTS D ON B.CONTRACT_ID = D.CONTRACT_ID
        LEFT OUTER JOIN PEOPLE_SOFT_DATA E ON A.INVOICE_NUMBER = E.INVOICE_NUMBER_ID
        LEFT OUTER JOIN PEOPLE_SOFT_PAYMENT_STATUS_TYPE F ON E.STATUS = F.PEOPLE_SOFT_PAYMENT_STATUS_TYPE_ID

我得到以下结果:

AGENCY_NAME PROJECT_NUMBER PROJECT_NAME CONTRACT_NO PROJECT_START_ 7月8月

Test Agency 1   proj54891   Test Project Name 1 C567HR8E    2012-05-23 00:00:00.000 NULL    NULL
Test Agency 1   proj54891   Test Project Name 1 C567HR8E    2012-05-23 00:00:00.000 NULL    Rejected- Grants-09/25/2013
Test Agency 1   proj54891   Test Project Name 1 C567HR8E    2012-05-23 00:00:00.000 Approved- Administrator-09/25/2013  NULL
Test Agency 1488    proj54891   Test Project Name 34    C5676542H9  2013-04-03 00:00:00.000 Approved-Agency-10/12/2013  NULL

如何更改它以获得以下结果:

AGENCY_NAME PROJECT_NUMBER  PROJECT_NAME    CONTRACT_NO PROJECT_START_DATE  July    August

Test Agency 1   proj54891   Test Project Name 1 C567HR8E    2012-05-23 00:00:00.000 Approved- Administrator-09/25/2013      Rejected- Grants-09/25/2013
Test Agency 1488    proj54891   Test Project Name 34    C5676542H9  2013-04-03 00:00:00.000 Approved-Agency-10/12/2013  NULL

以便类似的代理商,project_number和项目名称只在一行中? 我只需要将类似项目分组到一行。

感谢。

2 个答案:

答案 0 :(得分:0)

您可以使用GROUP BY语句对结果进行分组。 在这种情况下,我认为它会是这样的:

  GROUP BY(C.AGENCY_NAME, B.PROJECT_NUMBER)

如果要选择某个聚合值,请使用此选项。例如,某个列的SUM,或每个组中行数的简单COUNT。

否则,如果您不想聚合某些内容,但只想知道每个不同的条目,那么您将使用SELECT DISTINCT。所以这就像是:

  SELECT DISTINCT(C.AGENCY_NAME, B.PROJECT_NUMBER)

所以,这取决于你想要做什么。

答案 1 :(得分:0)

您可以使用DISTINCT:

SELECT DISTINCT C.AGENCY_NAME, B.PROJECT_NUMBER, B.PROJECT_NAME, D.CONTRACT_NO, 
            B.PROJECT_START_DATE,
            CASE WHEN E.CHECK_AMOUNT IS NOT NULL AND A.MONTH = 'JUL' THEN
                F.NAME + ' ' + CONVERT(VARCHAR(10), CHECK_DATE, 101) + ' ' + CASE WHEN CONVERT(VARCHAR(10), CHECK_NUMBER) IS NOT NULL THEN 'CHK# ' END 
                + CONVERT(VARCHAR(10), CHECK_NUMBER) ELSE /*START CODE IF PEOPLESOFT DATA DOESN'T EXIST*/
                (SELECT TOP 1 CASE WHEN STATUS = 1 THEN 'Approved-' WHEN STATUS = 3 THEN 'Hold-' ELSE 'Rejected-' END
                    + WORKFLOW_NAME + '-' + CONVERT(VARCHAR(10), DATE, 101) FROM FINANCE_WORKFLOW_DETAILS G, FINANCE_WORKFLOW H 
                    WHERE G.WORKKFLOW_ID_STATE = H.FINANCE_WORKFLOW_ID AND G.INVOICE_ID = A.INVOICE_NUMBER AND A.PROGRAM_ID = G.PROGRAM_ID
                    AND (A.MONTH = 'JUL') ORDER BY DATE DESC) END 'July',

            CASE WHEN E.CHECK_AMOUNT IS NOT NULL AND A.MONTH = 'AUG' THEN
                F.NAME + ' ' + CONVERT(VARCHAR(10), CHECK_DATE, 101) + ' ' + CASE WHEN CONVERT(VARCHAR(10), CHECK_NUMBER) IS NOT NULL THEN 'CHK# ' END 
                + CONVERT(VARCHAR(10), CHECK_NUMBER) ELSE /*START CODE IF PEOPLESOFT DATA DOESN'T EXIST*/
                (SELECT TOP 1 CASE WHEN STATUS = 1 THEN 'Approved-' WHEN STATUS = 3 THEN 'Hold-' ELSE 'Rejected-' END
                    + WORKFLOW_NAME + '-' + CONVERT(VARCHAR(10), DATE, 101) FROM FINANCE_WORKFLOW_DETAILS G, FINANCE_WORKFLOW H 
                    WHERE G.WORKKFLOW_ID_STATE = H.FINANCE_WORKFLOW_ID AND G.INVOICE_ID = A.INVOICE_NUMBER AND A.PROGRAM_ID = G.PROGRAM_ID
                    AND A.MONTH = 'AUG' ORDER BY DATE DESC) END 'August'

        FROM EXPENSES A
        INNER JOIN PROGRAMS B ON A.PROGRAM_ID = B.PROGRAM_ID
        INNER JOIN AGENCIES C ON B.AGENCY_ID = C.AGENCY_ID
        INNER JOIN CONTRACTS D ON B.CONTRACT_ID = D.CONTRACT_ID
        LEFT OUTER JOIN PEOPLE_SOFT_DATA E ON A.INVOICE_NUMBER = E.INVOICE_NUMBER_ID
        LEFT OUTER JOIN PEOPLE_SOFT_PAYMENT_STATUS_TYPE F ON E.STATUS = F.PEOPLE_SOFT_PAYMENT_STATUS_TYPE_ID

或使用GROUP BY

SELECT AGENCY_NAME, PROJECT_NUMBER, PROJECT_NAME, CONTRACT_NO, PROJECT_START_DATE, July, August
(
    SELECT C.AGENCY_NAME, B.PROJECT_NUMBER, B.PROJECT_NAME, D.CONTRACT_NO, 
                B.PROJECT_START_DATE,
                CASE WHEN E.CHECK_AMOUNT IS NOT NULL AND A.MONTH = 'JUL' THEN
                    F.NAME + ' ' + CONVERT(VARCHAR(10), CHECK_DATE, 101) + ' ' + CASE WHEN CONVERT(VARCHAR(10), CHECK_NUMBER) IS NOT NULL THEN 'CHK# ' END 
                    + CONVERT(VARCHAR(10), CHECK_NUMBER) ELSE /*START CODE IF PEOPLESOFT DATA DOESN'T EXIST*/
                    (SELECT TOP 1 CASE WHEN STATUS = 1 THEN 'Approved-' WHEN STATUS = 3 THEN 'Hold-' ELSE 'Rejected-' END
                        + WORKFLOW_NAME + '-' + CONVERT(VARCHAR(10), DATE, 101) FROM FINANCE_WORKFLOW_DETAILS G, FINANCE_WORKFLOW H 
                        WHERE G.WORKKFLOW_ID_STATE = H.FINANCE_WORKFLOW_ID AND G.INVOICE_ID = A.INVOICE_NUMBER AND A.PROGRAM_ID = G.PROGRAM_ID
                        AND (A.MONTH = 'JUL') ORDER BY DATE DESC) END 'July',

                CASE WHEN E.CHECK_AMOUNT IS NOT NULL AND A.MONTH = 'AUG' THEN
                    F.NAME + ' ' + CONVERT(VARCHAR(10), CHECK_DATE, 101) + ' ' + CASE WHEN CONVERT(VARCHAR(10), CHECK_NUMBER) IS NOT NULL THEN 'CHK# ' END 
                    + CONVERT(VARCHAR(10), CHECK_NUMBER) ELSE /*START CODE IF PEOPLESOFT DATA DOESN'T EXIST*/
                    (SELECT TOP 1 CASE WHEN STATUS = 1 THEN 'Approved-' WHEN STATUS = 3 THEN 'Hold-' ELSE 'Rejected-' END
                        + WORKFLOW_NAME + '-' + CONVERT(VARCHAR(10), DATE, 101) FROM FINANCE_WORKFLOW_DETAILS G, FINANCE_WORKFLOW H 
                        WHERE G.WORKKFLOW_ID_STATE = H.FINANCE_WORKFLOW_ID AND G.INVOICE_ID = A.INVOICE_NUMBER AND A.PROGRAM_ID = G.PROGRAM_ID
                        AND A.MONTH = 'AUG' ORDER BY DATE DESC) END 'August'

            FROM EXPENSES A
            INNER JOIN PROGRAMS B ON A.PROGRAM_ID = B.PROGRAM_ID
            INNER JOIN AGENCIES C ON B.AGENCY_ID = C.AGENCY_ID
            INNER JOIN CONTRACTS D ON B.CONTRACT_ID = D.CONTRACT_ID
            LEFT OUTER JOIN PEOPLE_SOFT_DATA E ON A.INVOICE_NUMBER = E.INVOICE_NUMBER_ID
            LEFT OUTER JOIN PEOPLE_SOFT_PAYMENT_STATUS_TYPE F ON E.STATUS = F.PEOPLE_SOFT_PAYMENT_STATUS_TYPE_ID
) a
GROUP BY AGENCY_NAME, PROJECT_NUMBER, PROJECT_NAME, CONTRACT_NO, PROJECT_START_DATE, July, August

http://www.learn-with-video-tutorials.com - IT视频教程