如何在sql表中合并空列

时间:2014-06-16 08:27:20

标签: sql-server

我想将null列与相同的用户名或userid合并,其中quarter是不同的,如果username1,2,3的用户名相同,根据以下查询,它显示的是不同行中不同季度的相同用户名,但我想要在同一行中具有不同的季度和相同的用户名

enter image description here

    ALTER PROCEDURE [dbo].[test]
--@USERID UNIQUEIDENTIFIER,
@BASESTARTDATE DATE,
@BASEENDDATE DATE,
@CASETYPEID VARCHAR(40),
@GROUPTYPE VARCHAR(40),
@COMPANYID VARCHAR(40),
@DEPTID VARCHAR(40)
   AS
    BEGIN
SET NOCOUNT ON

--CREATE TEMPORARY TABLE FOR INSERTING CALCULATED QUARTER
CREATE TABLE #QUARTERTEMP(QUARTER  VARCHAR(10),STARTDATE DATE,ENDDATE DATE,COUNTROW INT)

DECLARE @STARTDATETEMP DATETIME
DECLARE @ENDDATETEMP DATETIME
DECLARE @COUNTQUARTER INT
DECLARE @COUNTERCOUNT INT
SELECT @STARTDATETEMP=@BASESTARTDATE , @ENDDATETEMP=@BASEENDDATE
;WITH QUARTERS AS (
    SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@STARTDATETEMP),0) AS DT,
           DATEADD(DD, -1,DATEADD(QQ,DATEDIFF(QQ,0,@STARTDATETEMP)+1,0)) AS DATEEND
    UNION ALL
    SELECT DATEADD(QUARTER,1,DT),DATEADD(QUARTER,1,DATEEND) FROM QUARTERS
    WHERE DT < DATEADD(QUARTER,DATEDIFF(QUARTER,0,@ENDDATETEMP),0)

)
INSERT INTO #QUARTERTEMP
SELECT 'Q' + DATENAME(QQ,DT) + '-' + CAST(RIGHT(YEAR(DT)+ 0,2) AS VARCHAR(50)),DT AS 'STARTDATE',DATEEND AS 'ENDDATE',ROW_NUMBER() OVER (ORDER BY DT)FROM QUARTERS
--SELECT * FROM #QUARTERTEMP
/*DECLARE LOCAL VARIABLES*/
DECLARE @QUARTERNAME AS VARCHAR(10)
DECLARE @BEGINDATE AS DATE
DECLARE @ENDDATE AS DATE
SET @COUNTERCOUNT = 1
SELECT @COUNTQUARTER = COUNT(*) FROM #QUARTERTEMP
DECLARE @RESPONSEVALUE AS DECIMAL(9,1)
DECLARE @COUNT AS INT
DECLARE @ALLAVG  AS DECIMAL(9,2)

/*CREATE TEMP TABLE FOR INSERTING ALL RECORDS OF USERS*/
CREATE TABLE #TEMPUSER(USERID UNIQUEIDENTIFIER, USERNAME  VARCHAR(100),[QUARTER] VARCHAR(40) NULL,[AVG] DECIMAL (9,2) NULL,[AVGALL] DECIMAL (9,2) NULL)

    /*START OF WHILE LOOP*/
    WHILE (@COUNTERCOUNT <= @COUNTQUARTER)
    BEGIN

        /*FETCH QUARTERS TABLE QUARTERWISE*/
        SELECT @QUARTERNAME = [QUARTER],@BEGINDATE=STARTDATE,@ENDDATE = ENDDATE FROM #QUARTERTEMP WHERE COUNTROW = @COUNTERCOUNT
        print(@BEGINDATE)
        print(@ENDDATE)
        IF @DEPTID IS NOT NULL
        BEGIN
        PRINT('IN DEPT')
            /*DEPARTMENT AVG*/
            CREATE TABLE #TEMPALLUSER(USERID UNIQUEIDENTIFIER, USERNAME  VARCHAR(100),[QUARTER] VARCHAR(40) NULL,[AVG] DECIMAL (9,2) NULL,[AVGALL] DECIMAL (9,2) NULL)

            SELECT  @ALLAVG = ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS  S 
            ON SR.SURVEYID = S.SURVEYID 
            LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
            LEFT OUTER JOIN USERS U ON  ST.IDENTIFICATION = U.USERID
            INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
            INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
            INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
            INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
            --WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=@USERIDENTIFICATION)) 
            WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = @DEPTID)
            AND (PC.PARENTID=@CASETYPEID OR PC.CHILDID=@CASETYPEID)
            AND (1=CASE WHEN ((@GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=@GROUPTYPE)) THEN 1 ELSE 0 END)
            AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99
            AND CAST(S.RESPONSEDATE AS DATE) BETWEEN @BEGINDATE AND @ENDDATE

            /*INSERT VALUES IN TEMPALLUSER TABLE*/
            INSERT INTO #TEMPALLUSER
            SELECT U.USERID,U.NAME1,@QUARTERNAME,ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2),@ALLAVG FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS  S 
            ON SR.SURVEYID = S.SURVEYID 
            LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
            LEFT OUTER JOIN USERS U ON  ST.IDENTIFICATION = U.USERID
            INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
            INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
            INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
            INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
            --WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=@USERIDENTIFICATION)) 
            WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = @DEPTID) AND 
            (PC.PARENTID=@CASETYPEID OR PC.CHILDID=@CASETYPEID)
            AND (1=CASE WHEN ((@GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=@GROUPTYPE)) THEN 1 ELSE 0 END)
            AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99 
            AND CAST(S.RESPONSEDATE AS DATE) BETWEEN @BEGINDATE AND @ENDDATE
            GROUP BY U.USERID, U.NAME1
            ORDER  BY ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) DESC

            INSERT INTO #TEMPUSER
            SELECT * FROM #TEMPALLUSER  

            print(@COUNT)
            SELECT @COUNT = COUNT(*) FROM  #TEMPALLUSER
            IF @COUNT = 0
            BEGIN
                INSERT INTO #TEMPUSER VALUES(NULL,'',@QUARTERNAME,0.0,0.0)
            END
            DROP TABLE #TEMPALLUSER
        END /*END OF IF LOOP (DEPTID IS NOT NULL)*/

        ELSE /*START OF ELSE CONDITION*/
        BEGIN
            PRINT('IN COMP')            
            /*COMPANY AVG*/
            SELECT @ALLAVG = ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2)  FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS  S 
            ON SR.SURVEYID = S.SURVEYID 
            LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
            LEFT OUTER JOIN USERS U ON  ST.IDENTIFICATION = U.USERID
            INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
            INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
            INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
            INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
            --WHERE (U.PARENTUSERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT PARENTUSERID FROM USERS WHERE USERS.USERID= (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=@USERIDENTIFICATION))) OR
            --U.PARENTUSERID = (SELECT PARENTUSERID FROM USERS WHERE USERS.USERID= (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=@USERIDENTIFICATION))) AND
            WHERE ((U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID =@COMPANYID)) 
            OR U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID=@COMPANYID))) AND 
            U.USERTYPEID = 3 AND (PC.PARENTID=@CASETYPEID OR PC.CHILDID=@CASETYPEID)
            AND (1=CASE WHEN ((@GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=@GROUPTYPE)) THEN 1 ELSE 0 END)
            AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99
            AND CAST(S.RESPONSEDATE AS DATE) BETWEEN @BEGINDATE AND @ENDDATE

            /*INSERT VALUES IN TEMPALLUSER TABLE*/
            INSERT INTO #TEMPALLUSER
            SELECT U.USERID,U.NAME1,@QUARTERNAME,ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2),@ALLAVG FROM SURVEYRESPONSES SR LEFT OUTER JOIN SURVEYS  S 
            ON SR.SURVEYID = S.SURVEYID 
            LEFT OUTER JOIN SURVEYTARGETS ST ON S.SURVEYTARGETID = ST.SURVEYTARGETID
            LEFT OUTER JOIN USERS U ON  ST.IDENTIFICATION = U.USERID
            INNER JOIN [DBO].[SURVEYDEFINITIONS] SD ON S.SURVEYDEFINITIONID=SD.SURVEYDEFINITIONID
            INNER JOIN [DBO].[PARENTCHILDS] PC ON SD.SURVEYDEFINITIONTYPEID=PC.CHILDID
            INNER JOIN [DBO].[MASTERQUESTIONS] M ON SR.MASTERQUESTIONID=M.MASTERQUESTIONID
            INNER JOIN [DBO].[QUESTIONGROUPS] Q ON M.QUESTIONGROUPID=Q.QUESTIONGROUPID
            --WHERE U.USERID IN (SELECT USERID FROM USERS WHERE USERS.PARENTUSERID = (SELECT TOP 1 PARENTUSERID FROM USERS WHERE USERS.IDENTIFICATION=@USERIDENTIFICATION)) 
            WHERE((U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID =@COMPANYID)) 
            OR U.USERID IN (SELECT USERID FROM USERS WHERE PARENTUSERID=@COMPANYID)))
            AND (PC.PARENTID=@CASETYPEID OR PC.CHILDID=@CASETYPEID)
            AND (1=CASE WHEN ((@GROUPTYPE= '-1') OR (Q.QUESTIONGROUPID=@GROUPTYPE)) THEN 1 ELSE 0 END)
            AND SR.RESPONSEVALUE != -2147483648 AND S.SURVEYSTATUSID IN(6) AND S.SURVEYSTATUSID != 99 
            AND CAST(S.RESPONSEDATE AS DATE) BETWEEN @BEGINDATE AND @ENDDATE
            GROUP BY U.USERID, U.NAME1
            ORDER  BY ROUND(AVG(CAST(RESPONSEVALUE AS FLOAT)), 2) DESC

            SELECT @COUNT = COUNT(*) FROM  #TEMPALLUSER
            IF @COUNT = 0
            BEGIN
                INSERT INTO #TEMPALLUSER VALUES(NULL,'',@QUARTERNAME,0.0,0.0)
            END

        END /*END OF IF ELSE LOOP*/
        SET @COUNTERCOUNT = @COUNTERCOUNT + 1
        SET @BEGINDATE = '1900-01-01'
        SET @ENDDATE = '1900-01-01'
    END /*END WHILE LOOP */

    /*FETCH DATA FROM TEMP TABLE*/
    DECLARE @COLS AS NVARCHAR(MAX),
        @QUERY  AS NVARCHAR(MAX);

    SELECT @COLS = STUFF((SELECT DISTINCT ',' + QUOTENAME(T.QUARTER) 
                        FROM #TEMPUSER T 
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')

    SET @QUERY = 'SELECT DISTINCT USERID,USERNAME,AVGALL, ' + @COLS + ' FROM 
                 (
                     SELECT DISTINCT T.USERID
                            , T.USERNAME
                            ,T.AVGALL
                            , T.QUARTER
                            , T.AVG
                        FROM #TEMPUSER T

                ) X
                PIVOT 
                (
                    MIN(AVG)
                    FOR QUARTER IN (' + @COLS + ')
                ) P '

    EXECUTE(@QUERY)

    DROP TABLE #TEMPUSER    

END

GO

在这张图片中,同样的用户名/用户名rahul在q1-14等不同的季度有平均值..但是在第1行中它在q1-14中有平均值,之后在第2行中平均值是q2-14,所以在..但我想删除空列并合并行1/2/3具有相同的用户名,但在不同的行中平均,所以我希望它在单行。

  

所以我想这样如下图:   enter image description here

1 个答案:

答案 0 :(得分:1)

您只能GROUPSUM生成的表格的行:

SELECT USERID, USERNAME, MIN(AVGALL) as AVGALL, 
       SUM(Q1-14) as Q114, SUM(Q2-14) as Q214, SUNM(Q4-13) as Q413
FROM [TABLE]
GROUP BY USERID, USERNAME

要与查询一起使用,可以将结果推送到临时表中。只需使用以下内容替换您对EXECUTE(@QUERY)的通话:

-- select your results in to a temp table
SELECT INTO #T1 execute ('execute ' + @QUERY)

-- Perform the group and sum operations on the temp table to output results
SELECT USERID, USERNAME, MIN(AVGALL) as AVGALL, 
       SUM(Q1-14) as Q114, SUM(Q2-14) as Q214, SUNM(Q4-13) as Q413
FROM [#T1]
GROUP BY USERID, USERNAME