Postgresql - 如何在表中获取另一个表中没有匹配项的条目

时间:2012-02-24 10:15:34

标签: postgresql

我有一个问题,但我真的不知道如何问它!请耐心等待:

SELECT      sc.*, 
        scd.siteid, scd.desc_frontend
FROM        shipping_code sc
LEFT OUTER JOIN shipping_code_description scd
    ON          scd.shippingid=sc.shippingid
    AND         scd.siteid IN (SELECT siteid FROM site_international WHERE published='t')

为了解释上述情况,我们在一个名为“shipping_code”的表格中提供了运送(递送)代码,并且由于我们有一个多语言网站,因此我们在“shipping_code_description”中提供了另一个用于这些代码的语言描述的表格。 我们还有一个名为“site_international”的表格,其中包含以下字段:'siteid'(网站的ID - 例如英国,DE,FR ..(英语,德语,法语..)和'已发布'(布尔字段,即网站是否有效?)

上述SELECT查询获取所有送货代码,仅包含这些已发布网站的语言描述。

现在,我们还想知道哪些运输代码在某些网站中没有描述。如果运输代码是全新的,那么将为该代码返回1行(因为LEFT OUTER JOIN)。 'scd.siteid'和'scd.desc_frontend'将为NULL。

但是,如果存在英国(英语)站点的描述,但不存在FR和DE的描述,则上述查询将返回一行,而不是三行。如何判断特定货运代码缺少DE和FR描述?

以下是我的选择:

1)我可以以某种方式在一个查询中完成所有操作。必须有一种方法(我之前从未使用过UNION,EXCEPT等,我不确定这些是否应该使用)。

2)或者我可以简单地做另一个查询     SELECT siteid FROM site_international WHERE published ='t'

以上将给我所有发布的网站。然后,使用PHP(我用来编码我的网站),对于上面较大的查询的每个结果,我会检查并查看是否缺少任何描述。例如。上述siteid查询将返回3个ID(UK,DE,FR)。然后,如果特定的货运代码只返回一个英国行,我就知道缺少DE和FR,我可以将其标记给我的客户。

请告知是否存在更好的选项“1”?

非常感谢!

2 个答案:

答案 0 :(得分:38)

也许我不明白你的问题,但是如果你想在表格中获得“在另一张表中没有匹配的条目”,我可以给你一个简单的片段。

从左表中选择不在右表中的所有行。

SELECT  l.*
FROM    t_left l
LEFT JOIN t_right r
ON      r.value = l.value
WHERE   r.value IS NULL

答案 1 :(得分:1)

我认为这就是你要找的东西。 Left Join获取所有可能的Shipping Code和Site Code对,然后它会在Descriptions表中找到哪些没有条目。这就是Exists子句所做的。

SELECT      
    Shipping_Code.*,
    Site_International.SiteID 
FROM        
    Shipping_Code 
    LEFT JOIN Site_International ON Site_International.Published = 't'
WHERE
    NOT EXISTS (
        SELECT
            NULL
        FROM
            Shipping_Code_Description
        WHERE
            Shipping_Code.ShippingID = Shipping_Code_Description.ShippingID
        AND SiteInternational.SiteID = Shipping_Code_Description.SiteID)