2014-09-13 4 views
1

У меня есть таблица, как показано ниже с деталями:Агрегатная функция в сводной таблице запроса с помощью SQL Server 2008 R2

CREATE TABLE testrf 
(
    cola INTEGER, 
    colb VARCHAR(10) 
) 

Вставка некоторые данные:

INSERT INTO testrf VALUES(1,'x') 
INSERT INTO testrf VALUES(1,'x') 
INSERT INTO testrf VALUES(2,'x') 
INSERT INTO testrf VALUES(3,'y') 
INSERT INTO testrf VALUES(4,'y') 
INSERT INTO testrf VALUES(5,'c') 
INSERT INTO testrf VALUES(6,'c') 
INSERT INTO testrf VALUES(7,'c') 
INSERT INTO testrf VALUES(8,'d') 
INSERT INTO testrf VALUES(3,'y') 
INSERT INTO testrf VALUES(12,'M1') 
INSERT INTO testrf VALUES(13,'L1') 
INSERT INTO testrf VALUES(14,'C2') 
INSERT INTO testrf VALUES(1,'c') 
INSERT INTO testrf VALUES(1,'d') 
INSERT INTO testrf VALUES(1,'L1') 


SELECT * FROM testrf; 

cola colb 
------------ 
1  x 
1  x 
2  x 
3  y 
4  y 
5  c 
6  c 
7  c 
8  d 
3  y 
1  c 
1  d 
12  M1 
13  L1 
14  C2 
1  L1 

Теперь я хочу, чтобы показать сводную таблицу для приведенных выше данных, для которого я написал запрос:

DECLARE @cols NVARCHAR(MAX) 
DECLARE @SQL NVARCHAR(MAX) 

SELECT @cols = STUFF ((SELECT DISTINCT '],[' + v.colb       
       FROM testrf AS v           
FOR XML PATH('')), 1, 2, '') + ']' 


SET @SQL = N'SELECT cola,TotalGroups,AvailableIn,'+ @cols +' 
    FROM      
    (SELECT v.cola,v.colb,(select count(distinct colb) from testrf) TotalGroups,c.AvailableIn 
     FROM testrf AS v 
     inner join 
     (select cola,count(case when colb>=1 then 1 else 0 end) AS AvailableIn FROM testrf 
     group by cola) c 
     on c.cola = v.cola                         
    ) p      
     PIVOT     
      (   
       count(colb)       
       FOR colb IN ('+ @cols + ')       
      ) AS pvt';  

    EXEC(@SQL)  

Я получаю это:

cola TotalGroups AvailableIn c C2 d L1 M1 x y 
---------------------------------------------------------- 
1  7   5  1 0 1 1 0 2 0 
2  7   1  0 0 0 0 0 1 0 
3  7   2  0 0 0 0 0 0 2 
4  7   1  0 0 0 0 0 0 1 
5  7   1  1 0 0 0 0 0 0 
6  7   1  1 0 0 0 0 0 0 
7  7   1  1 0 0 0 0 0 0 
8  7   1  0 0 1 0 0 0 0 
12  7   1  0 0 0 0 1 0 0 
13  7   1  0 0 0 1 0 0 0 
14  7   1  0 1 0 0 0 0 0 

Примечание: Пожалуйста, обратите внимание на row number 1 and 3. В значениях AvailableIn значения столбца равны 5 для 1-й строки, где доступными значениями для столбцов являются только 4, то есть c,d,L1,x остальное - это нули. А также номер строки 3, где AvailableIn равно 2, где доступные значения для столбцов составляют только 1, что равно y. Я думаю, что я застрял в aggregate function в пределах pivot query.

SQL Скрипки ->http://sqlfiddle.com/#!3/d1acc/8

+0

у вас есть все биты, было бы полезно иметь [sqlfiddle.] (http://sqlfiddle.com) – paqogomez

+0

Пожалуйста, проверьте SQL скрипку. – Meem

+0

есть аналогичный вопрос к этому недавно, но я вижу, что это другое –

ответ

1

Вместо подсчета, если colb больше 1 (что все ваши письма), вы хотите четкий список (как у вас есть в родительском запросе) из colb

Здесь было единственное изменение, я сделал:

(select cola,count(distinct colb) AS AvailableIn FROM testrf 

Fiddle

+0

Получил! Спасибо большое. – Meem

1

У вас есть вопросы?

INSERT INTO testrf VALUES(1,'x'); 
INSERT INTO testrf VALUES(1,'x'); 
... 
INSERT INTO testrf VALUES(1,'c'); 
INSERT INTO testrf VALUES(1,'d'); 
INSERT INTO testrf VALUES(1,'L1'); 

That is 5 references to ColA = 1 

c C2 d L1 M1 x y 
1 0 1 1 0 2 0 << adds to 5 

Есть некоторые рекомендации, я хотел бы добавить к вашему запросу

  1. использовать QUOTENAME() вместо жесткого кодирования скобках [].
  2. ColB является Varchar поэтому не используйте ПРИ ColB> = 1, используйте COLB> = '1'
  3. COUNT() добавляет один для каждого ненулевого значения, поэтому не используйте else 0 внутри счетчика

    DECLARE @cols NVARCHAR(MAX), @SQL NVARCHAR(MAX) 
    
    SELECT @cols = STUFF ((SELECT DISTINCT ',' + QUOTENAME(v.colb)       
           FROM testrf AS v           
    FOR XML PATH('')), 1, 1, '') 
    
    
    SET @SQL = N'SELECT cola,TotalGroups,AvailableIn,'+ @cols +' 
        FROM      
        (SELECT v.cola,v.colb,(select count(distinct colb) from testrf) TotalGroups,c.AvailableIn 
         FROM testrf AS v 
         inner join 
         (select cola,count(case when colb>=''1'' then 1 end) AS AvailableIn FROM testrf 
         group by cola) c 
         on c.cola = v.cola                         
        ) p      
         PIVOT     
          (   
           count(colb)       
           FOR colb IN ('+ @cols + ')       
          ) AS pvt'  
    
    EXEC(@SQL) 
    
Смежные вопросы