SQL语句 - 优化

时间:2012-12-14 09:48:17

标签: sql oracle

我有这样的声明:

SELECT *
  FROM sgtn
 WHERE sgtn_kun_id IN (SELECT DISTINCT kun_id
                         FROM sgtn, kun
                        WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)
                              AND sgtn_kun_id = kun_id)

       AND sgtn_strasse IN (SELECT sgtn.sgtn_strasse
                              FROM sgtn
                             WHERE sgtn_kun_id IN (SELECT DISTINCT kun_id
                                                     FROM sgtn, kun
                                                    WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)
                                                          AND sgtn_kun_id = kun_id)

                             GROUP BY sgtn.sgtn_strasse
                            HAVING COUNT(sgtn_strasse) > 2);

LONG LIST OF EMAILS是: 'abc@domain.com', 'def@domain.com', 。 。 。 'xyz@domain.com'

正如你所看到的,我在这个查询中重复了一些subquerys。

我想知道是否以及如何替换LONG LIST OF EMAILS。它发生在我的声明中两次。是否可以编辑此查询,以便提到的LONG LIST OF EMAILS出现一次?

3 个答案:

答案 0 :(得分:2)

使用WITH子句:

WITH kun_list AS (
    SELECT DISTINCT kun_id
      FROM sgtn, kun
     WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)
           AND sgtn_kun_id = kun_id)

SELECT *
  FROM sgtn
 WHERE sgtn_kun_id IN (SELECT kun_id
                         FROM kun_list)

       AND sgtn_strasse IN (SELECT sgtn.sgtn_strasse
                              FROM sgtn
                             WHERE sgtn_kun_id IN (SELECT kun_id
                                                     FROM kun_list)

                             GROUP BY sgtn.sgtn_strasse
                            HAVING COUNT(sgtn_strasse) > 2);

答案 1 :(得分:1)

你可以试试这个:

with CTE as (
SELECT sgtn.*, count(sgtn_strasse) OVER (PARTITION BY sgtn_strasse) cnt
FROM sgtn
WHERE sgtn_kun_id IN (SELECT kun_id FROM kun 
                      WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS))
)

SELECT * FROM  CTE WHERE CNT > 2

答案 2 :(得分:1)

首先,您不需要使用

IN (SELECT DISTINCT kun_id
    FROM sgtn, kun
    WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)
    AND sgtn_kun_id = kun_id)

够了

IN (SELECT kun_id
    FROM kun
    WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS))

可以使用

检测列表中包含多个sgtn_strasse和电子邮件的行
select * from (
  SELECT s.*, count(*) over (partition by sgtn_strasse) cnt_strasse
  FROM sgtn s
  WHERE sgtn_kun_id IN (SELECT kun_id
                       FROM kun
                       WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS))
  )
WHERE cnt_strasse > 1;