如何在枢轴中获得不同的COUNT?

时间:2014-01-28 06:18:44

标签: sql-server pivot-table unpivot

我有一张桌子:

State   LAB GROUP   DATE    CODE    ID
UP  A   I   1-Jan   1   345
UP  R   S   1-Feb   1   456
UP  A   S   1-Jan   2   567
DL  R   S   1-Feb   3   678
DL  T   S   1-Jan   1   789
DL  A   S   1-Jan   2   900
MN  T   S   1-Jan   3   1011
MN  R   I   1-Feb   1   1122
MN  S   I   1-Feb   2   1233

我需要一个以下类型的数据透视表:

STATE   A   R   T   TOTAL
UP  2   1   0   3
DL  1   1   1   3
MN  0   1   1   2

每个州的每个实验室的识别号码。

然后我需要为以下列过滤透视表:

GROUP 日期 CODE

因此,第一个表将使上面的数据透视表仅计算具有GROUP = S的记录 第二个表将使上面的数据透视表只计算那些CODE = 1

的记录

等等,我希望提出多个条件。并逐个生成几个表并导出它们。

如果在SQL中可以这样做,请告诉我!由于表的大小,我排除了excel vba(源表将有大约800,000条记录)。

4 个答案:

答案 0 :(得分:2)

试试这个: -

Select [State],[A],[R],[T],Total = [A] + [R]+ [T]
from 
(
    Select [State],
           [A] = Sum(Case when LAB='A' then 1 else 0 END) ,
           [R] = Sum(Case when LAB='R' then 1 else 0 END) ,
           [T] = Sum(Case when LAB='T' then 1 else 0 END) 
   from YourTable
   group by [State]
)a

SQL FIDDLE

答案 1 :(得分:1)

CREATE TABLE #t(States VARCHAR(10),LAB VARCHAR(5),GROUPs VARCHAR(5),DATEs VARCHAR(10),CODE INT,ID INT)
INSERT INTO #t values('UP','A','I','1-Jan',1,345)
INSERT INTO #t values('UP','R','S','1-Feb',1,456)
INSERT INTO #t values('UP','A','S','1-Jan',2,567)
INSERT INTO #t values('DL','R','S','1-Feb',3,678)
INSERT INTO #t values('DL','T','S','1-Jan',1,789)
INSERT INTO #t values('DL','A','S','1-Jan',2,900)
INSERT INTO #t values('MN','T','S','1-Jan',3,1011)
INSERT INTO #t values('MN','R','I','1-Feb',1,1122)
INSERT INTO #t values('MN','S','I','1-Feb',2,1233)



SELECT States,ISNULL(A,0) A,ISNULL(R,0) R,ISNULL(T,0) T,ISNULL(A,0)+ISNULL(R,0)+ISNULL(T,0) total
FROM 
(
    SELECT States,LAB,Count(ID) AS cnt FROM #t GROUP BY States,LAB /*apply GROUP DATE CODE condition here*/ 
) AS PVT
PIVOT(MAX(cnt) FOR LAB IN (A,R,T)) pvt

答案 2 :(得分:1)

您的样本表

SELECT * INTO #TEMP FROM
(               
    SELECT 'UP' [State],'A' LAB,'I' [GROUP],'1-Jan' [DATE],1 CODE,345 ID
    UNION ALL
    SELECT 'UP','R','S','1-Feb',1,456
    UNION ALL
    SELECT 'UP','A','S','1-Jan',2,567
    UNION ALL
    SELECT 'DL','R','S','1-Feb',3,678
    UNION ALL
    SELECT 'DL','T','S','1-Jan',1,789
    UNION ALL
    SELECT 'DL','A','S','1-Jan',2,900
    UNION ALL
    SELECT 'MN','T','S','1-Jan',3,1011
    UNION ALL
    SELECT 'MN','R','I','1-Feb',1,1122
    UNION ALL
    SELECT 'MN','S','I','1-Feb',2,1233  
)TAB

现在你需要得到每个州的不同计数,并得到总和作为显示Total的结果 在结果中。

SELECT DISTINCT [State],LAB,SUM(CNT) CNT 
INTO #NEWTABLE
FROM 
(
    SELECT DISTINCT 
    [State],LAB,
    CASE WHEN [State] IS NULL THEN NULL ELSE COUNT([State]) OVER(PARTITION BY [State],LAB) END CNT  
    FROM #TEMP
)TAB
GROUP BY [State],LAB
WITH ROLLUP

现在我们需要获取pivot(@cols)和列的不同列来识别和替换null(0)(@NullToZeroCols)

DECLARE @cols NVARCHAR (MAX)
DECLARE @NullToZeroCols NVARCHAR (MAX)


SET @cols = SUBSTRING((SELECT DISTINCT ',['+LAB+']' FROM #NEWTABLE GROUP BY LAB  FOR XML PATH('')),2,8000)

SET @NullToZeroCols = SUBSTRING((SELECT DISTINCT ',ISNULL(['+LAB+'],0) AS ['+LAB+']' 
FROM #NEWTABLE GROUP BY LAB FOR XML PATH('')),2,8000)

使用#NEWTABLE加入轮回查询以获取每个州的Total

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT P.State,' + @NullToZeroCols + ',T2.CNT TOTAL FROM 
             (
                 SELECT DISTINCT [State],LAB,CNT FROM #NEWTABLE
             ) x
             PIVOT 
             (
                 SUM(CNT)
                 FOR [LAB] IN (' + @cols + ')
            ) p
            JOIN #NEWTABLE T2 ON P.[STATE]=T2.[STATE] 
            WHERE P.State IS NOT NULL AND T2.LAB IS NULL AND T2.[STATE] IS NOT NULL;'

EXEC SP_EXECUTESQL @query

这是你的结果

enter image description here

这是SQLFiddle http://sqlfiddle.com/#!3/c2588/1(如果它在加载页面时显示任何错误,只需单击RUNSQL,它就会起作用)

现在,如果你想得到每个州的每个实验室的 DISTINCT COUNT ID 的结果,只需更改

OVER(PARTITION BY [State],LAB)

OVER(PARTITION BY [State],LAB,Id)

执行数据透视查询后将显示以下结果

enter image description here

答案 3 :(得分:0)

另一种使用PIVOT的解决方案:

WITH PivotInUse AS (
	SELECT state,lab,COUNT(*) AS cnt
		FROM YourTable
		GROUP BY state,lab
		)
SELECT STATE
	,COALESCE([A], 0) AS A
	,COALESCE([R], 0) AS R
	,COALESCE([T], 0) AS T
	,COALESCE([A], 0) + COALESCE([R], 0) + COALESCE([T], 0) AS TOTAL
FROM PivotInUse
PIVOT(SUM(cnt) FOR lab IN ([A],[R],[T])) AS p;