SQL 可以简化吗?

SQL simplification possible?

有人问我以下关于 table 的问题

Display NPRO and LIBELLE from SAPIN products that are ordered only in Toulouse

这是我的答案(正确),但我觉得可以以某种方式简化它。

有没有办法让它更简单?

select npro, libelle
from produit
where libelle like '%SAPIN%'
and npro in 
(select npro from detail where ncom in
(select ncom from commande where ncli in
(select ncli from client where localite='Toulouse')))
and npro not in
(select npro from detail where ncom in
(select ncom from commande where ncli in
(select ncli from client where localite<>'Toulouse')))

一种使其更易于阅读的方法是使用:

SELECT p.npro, p.libelle
FROM produit p
JOIN detail d
  ON p.npro = d.npro
JOIN commande c
  ON d.ncom = c.ncom
JOIN client cl
  ON cl.ncli = c.ncli
WHERE p.libelle LIKE '%SAPIN%'
GROUP BY p.npro, p.libelle
HAVING COUNT(CASE WHEN cl.localite = 'Toulouse' THEN 1 END) > 0
   AND COUNT(CASE WHEN cl.localite <> 'Toulouse' THEN 1 END) = 0

工作原理:

  • 加入您需要的表
  • 从包含 SAPIN
  • 的产品 p.libelle 中过滤
  • p.nprop.libelle
  • 分组
  • 聚合过滤结果:第一个计数 localite 等于 Touluse,第二个计数 localite.

EXISTS+NOT EXISTS 最简单。 (恕我直言)

SELECT npro, libelle
FROM produit p
WHERE p.libelle LIKE '%SAPIN%'
AND EXISTS (
        SELECT *  
        FROM detail d  
        JOIN commande co ON co.ncom = d.ncom
        JOIN client cl ON cl.ncli = co.ncli
        WHERE d.npro = p.npro
        AND cl.localite = 'Toulouse'
        )
AND NOT EXISTS (
        SELECT *
        FROM detail d
        JOIN commande co ON co.ncom = d.ncom
        JOIN client cl ON cl.ncli = co.ncli
        WHERE d.npro = p.npro
        AND cl.localite <> 'Toulouse'
        );