sql - Postgres 中的左外连接不返回空值

标签 sql postgresql

下载由下载次数、下载时间 ID 和 buno ID 组成。 故障由故障代码、下载时间 ID、状态和类型组成。一个下载可以有很多错误,可以在下载时间id上加入。

给定一组故障代码,结果必须包含每个故障代码和相应的故障计数。如果在下载中未找到故障代码,则必须返回故障代码且故障计数为零。

这个问题似乎需要一个 OUTER JOIN,但在 Postgres 上没有看到它按预期工作,因为它似乎没有从 LEFT 表返回带有空值的集合。

查询如下,为简洁起见省略了一些细节:

SELECT  f.faultcode, f.downloadtimeid, d.downloadtime, count(*) as faultcount 
FROM    download_time d 
LEFT OUTER JOIN fs_fault f ON f.downloadtimeid = d.id
    AND f.faultcode IN (1000,1100)
    AND f.statusid IN(2, 4)
WHERE (d.downloadtime BETWEEN '04/11/2011' AND '05/01/2012')
    AND d.bunoid = 166501
GROUP BY d.bunoid, f.downloadtimeid, d.downloadtime, f.faultcode

第二天,我进行了编辑以显示答案。所有答案都很接近,并且有各种帮助因素。然而,JayC 的答案是最接近的。 这是最终的 SQL,唯一的变化是采用错误代码 IN 语句的 WHERE 子句:

SELECT  f.faultcode, f.downloadtimeid, d.downloadtime, count(*) as faultcount
FROM    download_time d  
RIGHT OUTER JOIN fs_fault f ON f.downloadtimeid = d.id
        AND f.statusid IN(2, 4)
        AND d.downloadtime BETWEEN '04/11/2011' AND '05/01/2012'
        AND d.bunoid = 166501
WHERE f.faultcode IN (1000,1100)
GROUP BY d.bunoid, f.downloadtimeid, d.downloadtime, f.faultcode

谢谢大家的帮助!喜欢这个网站!

最佳答案

我给出我的答案是因为我对其他答案有很大的怀疑。您必须注意过滤器要求。请记住,where 子句在您的联接之后运行。因此,如果在引用非外部联接表的 where 子句中 有任何过滤要求,则您(在许多情况下)已经使您的外部联接无效。因此,对于您的 sql,似乎最简单的解决方案是使用正确的连接或适本地移动表名,然后将过滤条件移出 where 子句并移入连接子句。

SELECT  f.faultcode, f.downloadtimeid, d.downloadtime, count(*) as faultcount 
FROM    download_time d 
RIGHT OUTER JOIN fs_fault f ON 
    f.downloadtimeid = d.id
    AND f.faultcode IN (1000,1100)
    AND f.statusid IN(2, 4)
    AND d.downloadtime BETWEEN '04/11/2011' AND '05/01/2012')
    AND d.bunoid = 166501
GROUP BY d.bunoid, f.downloadtimeid, d.downloadtime, f.faultcode

我认为应该等效的另一种方式是

SELECT  f.faultcode, f.downloadtimeid, d.downloadtime, count(*) as faultcount 
FROM    download_time d 
RIGHT OUTER JOIN fs_fault f ON 
    f.downloadtimeid = d.id
    AND d.downloadtime BETWEEN '04/11/2011' AND '05/01/2012')
    AND d.bunoid = 166501
WHERE
    f.faultcode IN (1000,1100)
    AND f.statusid IN(2, 4)
GROUP BY d.bunoid, f.downloadtimeid, d.downloadtime, f.faultcode

因为 fs_fault 的过滤器要求在哪里并不严格。 (无论如何,您的 SQL 引擎都会改变这一切)。

编辑:这是一个SQLFiddle演示对 join 子句和 where 子句的过滤。

关于sql - Postgres 中的左外连接不返回空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10590234/

相关文章:

MySQL 不使用主索引

postgresql - 新用户在公共(public)架构上的默认权限?

perl - 插入 PostgreSQL/PostGIS 数据库太慢

mysql - 使用 INNER JOIN 处理两批列

sql - VIEW中的ORDER BY返回不同的结果SQL

mysql - 如何编写一个sql查询来内连接2个表而没有重复的数据?

mysql - 如何在查询分析器 MS SQL Server 中查看表结构

postgresql - 如果服务器在使用 dblink 时不请求密码,则非 super 用户无法连接

java - 使用 Java 处理 Postgresql 事务

postgresql - Postgres 隧道 SSH -L 在后台