SQL简化可能吗?

时间:2015-12-20 13:11:10

标签: sql postgresql relational-division

我被问到以下关于下表的问题

  

显示仅在中订购的SAPIN产品中的NPRO和LIBELLE   图卢兹

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

有没有办法让它变得更容易?

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')))

enter image description here

2 个答案:

答案 0 :(得分:1)

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

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

工作原理:

  • 连接您需要的表格
  • 从包含p.libelle
  • 的产品SAPIN进行过滤
  • 分组p.nprop.libelle
  • 过滤汇总结果:首先计算localite等于Touluse,然后计算其他localite

答案 1 :(得分:1)

EXISTS + NOT EXISTS是最简单的。 (IMHO)

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'
        );