Адаптация запроса для использования CTE - PullRequest
0 голосов
/ 31 января 2019

Я ищу использовать CTE в своем запросе, потому что я получаю такой же выбор, но я никогда раньше не использовал CTE, может ли кто-нибудь мне помочь?

Мне нужно, чтобы firstTable можно было использовать вдругие выбирают

SELECT firstTable.id as id,
   secondTable.holder as holder
FROM (
select tb3.id as id
from table1 tb1
inner join table2 tb2 on tb1.tb2_id = tb2.id
inner join table3 tb3 on tb2.tb3_id = tb3.id and tb3.id
inner join table4 tb4 on tb4.id = tb3.tb4_id and tb4.id = 1998
group by tb3.id) as firstTable
JOIN (
select id_holder,
       sum(temporaryTable.holder) as holder
from (
    select cast(tb4.helper as integer) as helper,
           count(distinct tb4.id) as holder,
           tb3.id as id_holder
    from table1 tb1
    inner join table2 tb2 on tb1.tb2_id = tb2.id
    inner join table3 tb3 on tb2.tb3_id = tb3.id and tb3.id
    inner join table4 tb4 on tb4.id = tb3.tb4_id and tb4.id = 1998
    group by tb3.id, tb4.helper
) as temporaryTable
where temporaryTable.helper between 7 and 8
group by id_holder) as secondTable
ON firstTable.id = temporaryTable.id_holder

Вот мой пробный запрос:

WITH temporary_table AS
  ( SELECT id,
           cast(resp.valor AS integer) AS holder,
           count(val) AS sumId
   FROM table1 tb1
   INNER JOIN table2 tb2 ON tb1.tb2_id = tb2.id
   INNER JOIN table3 tb3 ON tb2.tb3_id = tb3.id
   AND tb3.id
   INNER JOIN table4 tb4 ON tb4.id = tb3.tb4_id
   AND tb4.id = 1998
   GROUP BY tb3.id )
SELECT
  (SELECT SUM(sumId)
   WHERE holder = -10) AS p1,

  (SELECT SUM(sumId)
   WHERE holder = 78) AS p2,

  (SELECT SUM(sumId)
   WHERE holder = 1997) AS p3,
       id
FROM temporary_table
GROUP BY id,
         holder;

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Я просто приведу касательную к самому вопросу.

Я настоятельно советую вам НЕ использовать CTE вообще.Если вы хотите иметь элегантный запрос, который выглядит красиво, я считаю, что было бы лучше, просто правильно отформатируйте свои запросы.http://www.dpriver.com/pp/sqlformat.htm

Для CTE характерна медленная скорость, поскольку в большинстве случаев индекс не запускается должным образом.Я столько лет занимался SQL как профессией, я столкнулся с множеством проблем с производительностью в CTE.Сделать CTE быстрее - сложно, и я считаю, что усилия не стоят того.Они также затрудняют отладку и тестирование запросов, особенно когда в CTE много таблиц.Просто трудно разделить подзапросы, особенно тестирование, если предположение о предыдущем подзапросе все еще действует.

Вы также можете проверить по крайней мере ниже 500+ вопросов в stackoverflow относительно медленного CTE: https://stackoverflow.com/search?q=slow+cte

Мой совет - поместить данные во временную таблицу.Вы также можете удалить повторяющийся код, просто повторно используя временную таблицу.В качестве дополнительного бонуса для повышения производительности вы можете иметь индексы во временных таблицах.Вы не можете создавать индексы на лету в CTE.По моему мнению, единственная причина использования CTE - это рекурсивные CTE.https://www.essentialsql.com/recursive-ctes-explained/

0 голосов
/ 01 февраля 2019

Попробуйте этот запрос:

select tb3.id as id,
       count(distinct CASE WHEN tb4.helper between 7 and 8 THEN tb4.id END) as holder,
from table1 tb1
inner join table2 tb2 on tb1.tb2_id = tb2.id
inner join table3 tb3 on tb2.tb3_id = tb3.id and tb3.id
inner join table4 tb4 on tb4.id = tb3.tb4_id and tb4.id = 1998
group by tb3.id
0 голосов
/ 31 января 2019

Довольно просто использовать CTE для каждого подзапроса:

WITH firstTable AS (
    select tb3.id as id
    from table1 tb1
        inner join table2 tb2 on tb1.tb2_id = tb2.id
        inner join table3 tb3 on tb2.tb3_id = tb3.id and tb3.id
        inner join table4 tb4 on tb4.id = tb3.tb4_id and tb4.id = 1998
    group by tb3.id
), temporaryTable AS (
    select cast(tb4.helper as integer) as helper,
           count(distinct tb4.id) as holder,
           tb3.id as id_holder
    from table1 tb1
        inner join table2 tb2 on tb1.tb2_id = tb2.id
        inner join table3 tb3 on tb2.tb3_id = tb3.id and tb3.id
        inner join table4 tb4 on tb4.id = tb3.tb4_id and tb4.id = 1998
    group by tb3.id, tb4.helper
), secondTable AS (
select id_holder,
       sum(temporaryTable.holder) as holder
from temporaryTable
where temporaryTable.helper between 7 and 8
group by id_holder
)
    SELECT firstTable.id as id,
       secondTable.holder as holder
    FROM firstTable
        JOIN secondTable
            ON firstTable.id = temporaryTable.id_holder;
...