Два SQL-запроса для одного

Я хочу объединить два фрагмента кода в один, но получаю ошибку:

Часть 1

SELECT idstd,namestd, idmajor, 
      c1, c2, c3, c4, c5, c6, 
      c7, c8, c9, c10,c11,c12,
      c13,c14,c15 
FROM 
    (SELECT status, idstd,namestd, idmajor, 
           'C' + cast(row_number() 
            OVER (partition BY idstd, idmajor 
               ORDER BY (SELECT 1)) AS varchar(10)) col
     FROM tbcheked) src 
PIVOT (MAX(status) FOR col IN (C1, C2, C3, C4, C5, 
                               C6, C7, C8, C9, C10,
                               c11,c12,c13,c14,c15)) piv

Этот код предназначен для проверки, если столбец status имеет значения present, absent или же leave,

Пример:

id    |   c1      |   c2     |     c3  |     c4  |     c5  |
1        present     absent    present   leave     present

У меня есть второй кусок кода для подсчета статуса:

    SELECT idstd, 
           namemajor, 
           SUM(CASE WHEN status = 'present' 
                    THEN 1 
                    ELSE 0 
               END) AS present, 
           SUM(CASE WHEN status = 'absent' 
                    THEN 1 
                    ELSE 0 
               END) AS absent, 
           SUM(CASE WHEN status = 'leave' 
                    THEN 1 
                    ELSE 0 
                END) AS leave, 
   FROM tbcheked GROUP BY idstd, namemajor 
   ORDER BY idstd

Выход:

id     | present  |  absent  |  leave  |
1          3           1          1

Теперь я хочу объединить оба запроса:

id    |   c1      |   c2     |     c3  |     c4  |     c5  |  present  |  absent  |  leave  |
1        present     absent    present   leave     present     3            1         1

2 ответа

Используйте объединение для объединения вывода обоих запросов.

select a.*, b.*
from (query 1)a join (query 2)b on a.id=b.id; 

Рассматривайте каждую часть как подзапрос и присоединяйтесь к ним:

select
    <whatever>
from
        (
            SELECT idstd,namestd, idmajor, 
                  c1, c2, c3, c4, c5, c6, 
                  c7, c8, c9, c10,c11,c12,
                  c13,c14,c15 
            FROM 
                (SELECT status, idstd,namestd, idmajor, 
                       'C' + cast(row_number() 
                        OVER (partition BY idstd, idmajor 
                           ORDER BY (SELECT 1)) AS varchar(10)) col
                 FROM tbcheked) src 
            PIVOT (MAX(status) FOR col IN (C1, C2, C3, C4, C5, 
                                           C6, C7, C8, C9, C10,
                                           c11,c12,c13,c14,c15)) piv
        ) as PivotedBit
INNER JOIN -- or OUTER, depending on your requirement
        (
            SELECT idstd, 
                   namemajor, 
                   SUM(CASE WHEN status = 'present' 
                            THEN 1 
                            ELSE 0 
                       END) AS present, 
                   SUM(CASE WHEN status = 'absent' 
                            THEN 1 
                            ELSE 0 
                       END) AS absent, 
                   SUM(CASE WHEN status = 'leave' 
                            THEN 1 
                            ELSE 0 
                        END) AS leave, 
            FROM tbcheked GROUP BY idstd, namemajor 
            --ORDER BY idstd -- cannot have this in a sub-query
        ) as SummingBit
    on SummingBit.idstd = PivotedBit.idstd
    -- and any other common keys
    ORDER BY idstd

Это сделает два полных сканирования tbchekedтак что это не будет быстро.

У меня есть догадка, что добавление фиктивных столбцов к внутреннему выбору PIVOT запрос с использованием CASE операторы из суммирующего запроса, затем добавление SUM() к PIVOT пункт был бы лучше. Я не продумал это полностью, как бы то ни было.

Другие вопросы по тегам