создать рентабельный запрос - PullRequest
2 голосов
/ 07 марта 2011

Не могли бы вы помочь мне в создании запроса.У меня есть таблица, как показано ниже

Id            Info_Id                 Type
1              2                              2
2              6                              2
3              5                              3
4              8                              3
5              2                              3
6              2                              2
7              5                              2
8              8                              2
9              5                              2
10             8                              2
11             8                              2
12             5                              3
13             6                              3
14             8                              3

запрос должен быть оформлен так, чтобы сгруппировать его по "Info_Id".

Мне нужен вывод, как показано ниже, например:

Info_Id CountOfRec       Type2    Type3
2              3         2              1
5              4         2              2
6              2         1              1
8              5         3              2

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

select  Info_Id, count(Id)as CountOfRec,
(select count(Id)from tbl_TypeInfo where Info_Id = 5 AND Type = 2) as Type2,
(select count(Id)from tbl_ TypeInfo where Info_Id = 5 AND Type = 3) as Type3
 from tbl_TypeInfo
where Info_Id = 5
group by Info_Id

это был вывод,

Info_Id CountOfRec       Type2    Type3
5              4                              2              2

(я должен выполнить цикл для каждого «Info_id », чтобы получить нужный OP, есть тысячи записей и это отнимает много времени)

Я хотел получить выделенный вывод из таблицы.Обозначенный мною запрос неэффективен, и для этого найдется хорошее решение.

Ответы [ 3 ]

2 голосов
/ 07 марта 2011

Вы можете использовать оператор SQL Server PIVOT

SELECT  Info_ID
        , CountOfRec = [2] + [3]
        , Type2 = [2]
        , Type3 = [3]
FROM    (        
          SELECT  *
          FROM    (          
                    SELECT  *
                    FROM    tbl_TypeInfo
                   ) s 
          PIVOT   (COUNT(Id) FOR Type IN ([2], [3])) pvt 
        ) q

Тест

;WITH tbl_TypeInfo AS (
  SELECT [Id] = 1, [Info_Id] = 2, [Type] = 2
  UNION ALL SELECT 2, 6, 2
  UNION ALL SELECT 3, 5, 3
  UNION ALL SELECT 4, 8, 3
  UNION ALL SELECT 5, 2, 3
  UNION ALL SELECT 6, 2, 2
  UNION ALL SELECT 7, 5, 2
  UNION ALL SELECT 8, 8, 2
  UNION ALL SELECT 9, 5, 2
  UNION ALL SELECT 1, 8, 2
  UNION ALL SELECT 1, 8, 2
  UNION ALL SELECT 1, 5, 3
  UNION ALL SELECT 1, 6, 3
  UNION ALL SELECT 1, 8, 3
)
SELECT  Info_ID
        , CountOfRec = [2] + [3]
        , Type2 = [2]
        , Type3 = [3]
FROM    (        
          SELECT  *
          FROM    (          
                    SELECT  *
                    FROM    tbl_TypeInfo
                   ) s 
          PIVOT   (COUNT(Id) FOR Type IN ([2], [3])) pvt 
        ) q
2 голосов
/ 07 марта 2011

Вы можете использовать выражение CASE только для подсчета строк определенного типа:

SELECT Info_Id,
    COUNT(*) AS CountOfRec,
    COUNT(CASE WHEN Type = 2 THEN 1 ELSE NULL END) AS Type2
    COUNT(CASE WHEN Type = 3 THEN 1 ELSE NULL END) AS Type3
FROM tbl_TypeInfo
GROUP BY Info_Id

Добавьте WHERE Info_Id = 5, чтобы получить результаты только для определенного идентификатора.

Обновление : согласно комментариям, если вы не сохраняете таблицу идентификаторов, вам необходимо изменить свой список IN (..) на виртуальную "таблицу":

SELECT vt.id,
    COUNT(*) AS CountOfRec,
    COUNT(CASE WHEN Type = 2 THEN 1 ELSE NULL END) AS Type2,
    COUNT(CASE WHEN Type = 3 THEN 1 ELSE NULL END) AS Type3
FROM (
    SELECT 1 id
    UNION SELECT 2
    UNION SELECT 3
    UNION SELECT 5
    UNION SELECT 8 
  ) AS vt LEFT JOIN tbl_TypeInfo ON vt.id = tbl_TypeInfo.Info_Id
GROUP BY vt.id
0 голосов
/ 07 марта 2011

Это немного безумно, но если типы всегда, всегда 2 и 3, это можно представить как уравнение, где count(type2)+count(type3)=count(*) и 2*count(type2)+3*count(type3)=sum(*), чтобы вы могли что-то вроде

SELECT 3*c-s as Type2Count, s-2*c as Type3Count
FROM (SELECT COUNT(*) as C, SUM(Type) as S 
      FROM tbl_TypeInfo
      WHERE Info_Id = 5) SourceTable

Это будет молниеносно, однако, это чрезвычайно хрупко !!!! Если когда-либо изменятся типы или добавлен тип, это не будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...