Мне нужно определить строки, которые при группировке на самом высоком уровне не достигают счетчика, который больше порогового значения.Если строка соответствует пороговому значению на более низком уровне группировки, эти строки не рассматриваются для проверок более высокого уровня.
Например:
У меня есть значение, подобное этому, и порог равен 5.
COL_1 COL_2 COL_3
CH ZZZZZZ T77613
CH ZZZZZZ R537973
**CH 181600 19M8323**
**CH HYC440 RE575008**
**CH 211000 AE74215**
CH ZZZZZZ T77858
CH ZZZZZZ T76938
CH ZZZZZZ T77932
CH ZZZZZZ T76938
CH ZZZZZZ 14M7396
CH ZZZZZZ RE593267
CH ZZZZZZ RE593267
CH ZZZZZZ RE579130
CH ZZZZZZ 14M7296
CH ZZZZZZ RE580337
CH ZZZZZZ RE580337
необходимо выбирать только выделенные жирным шрифтом строки.
Я использую запрос, подобный приведенному ниже
WITH Step1 AS (
SELECT x1.*
FROM mytable AS x1
LEFT JOIN (
SELECT col_1
,col_2
,col_3
FROM mytable
GROUP BY col_1
,col_2
,col_3
HAVING COUNT(*) >= 5
) y1 ON x1.col_1 = y1.col_1
AND x1.col_2 = y1.col_2
AND x1.col_3 = y1.col_3
WHERE y1.col_1 IS NULL
AND y1.col_2 IS NULL
AND y1.col_3 IS NULL
)
,Step2 AS (
SELECT x1.*
FROM Step1 x1
LEFT JOIN (
SELECT col_1
,col_2
FROM Step1
GROUP BY col_1
,col_2
HAVING COUNT(*) >= 5
) y1 ON x1.col_1 = y1.col_1
AND x1.col_2 = y1.col_2
WHERE y1.col_1 IS NULL
AND y1.col_2 IS NULL
)
,Step3 AS (
SELECT x1.*
FROM Step2 x1
LEFT JOIN (
SELECT col_1
FROM Step2
GROUP BY col_1
HAVING COUNT(*) >= 5
) y1 ON x1.col_1 = y1.col_1
WHERE y1.col_1 IS NULL
)
SELECT *
FROM Step3
Этот запрос дает правильные результаты.Но если в таблице более 17000 строк, SQL-запрос просто зависает и время ожидания истекает.
Кто-нибудь знает, что идет не так, и какое лучшее решение можно предложить?
Обновление:
Я нашел несколько ответов здесь https://www.sqlshack.com/why-is-my-cte-so-slow/.После использования временной таблицы для хранения результатов первых двух CTE я смог выполнить запрос и получить результаты за 45 секунд.
WITH Step1 AS (
SELECT x1.*
FROM mytable AS x1
LEFT JOIN (
SELECT col_1
,col_2
,col_3
FROM mytable
GROUP BY col_1
,col_2
,col_3
HAVING COUNT(*) >= 5
) y1 ON x1.col_1 = y1.col_1
AND x1.col_2 = y1.col_2
AND x1.col_3 = y1.col_3
WHERE y1.col_1 IS NULL
AND y1.col_2 IS NULL
AND y1.col_3 IS NULL
)
,Step2 AS (
SELECT x1.*
FROM Step1 x1
LEFT JOIN (
SELECT col_1
,col_2
FROM Step1
GROUP BY col_1
,col_2
HAVING COUNT(*) >= 5
) y1 ON x1.col_1 = y1.col_1
AND x1.col_2 = y1.col_2
WHERE y1.col_1 IS NULL
AND y1.col_2 IS NULL
)
select * into #CTE2 from step2 ;
WITH Step3 AS (
SELECT x1.*
FROM #CTE2 x1
LEFT JOIN (
SELECT col_1
FROM Step2
GROUP BY col_1
HAVING COUNT(*) >= 5
) y1 ON x1.col_1 = y1.col_1
WHERE y1.col_1 IS NULL
)
SELECT *
FROM Step3 ;
Но это означает, что это уже не один SQL-запрос.