два 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

person user2668482    schedule 24.04.2014    source источник
comment
Подсказка: если у вас есть имена столбцов, оканчивающиеся на 1, 2, 3 и т. д., вы делаете это неправильно и вам нужно нормализовать базу данных.   -  person Jonathon Reinhart    schedule 24.04.2014


Ответы (2)


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

select a.*, b.*
from (query 1)a join (query 2)b on a.id=b.id; 
person G one    schedule 24.04.2014

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

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 было бы лучше. Однако я не продумал это до конца.

person Michael Green    schedule 24.04.2014