Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Postgres中的左外部联接不返回Null值_Sql_Postgresql - Fatal编程技术网

Sql Postgres中的左外部联接不返回Null值

Sql Postgres中的左外部联接不返回Null值,sql,postgresql,Sql,Postgresql,下载由下载时间、下载时间id和buno id组成。 故障由故障代码、下载时间id、状态和类型组成。一次下载可能有许多错误,并且可以在下载时间id上加入 给定一组故障代码,结果必须包含每个故障代码以及相应的故障计数。如果在下载中未找到故障代码,则必须返回故障代码,且故障计数为零 这个问题似乎需要一个外部联接,但在Postgres上并没有看到像预期的那样工作,因为它似乎没有从左表返回带有null的集合 查询如下,为了简洁起见,省略了一些细节: SELECT f.faultcode, f.downl

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

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

这个问题似乎需要一个外部联接,但在Postgres上并没有看到像预期的那样工作,因为它似乎没有从左表返回带有null的集合

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

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,唯一的更改是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

谢谢大家的帮助!爱这个网站

这将需要一个
右侧外部连接
。右外部联接包括右表中的所有值,其中左表中没有条目的
NULL
s(我不确定这是否适用于
GROUP BY
,但是…如果
fs_fault
是一个包含所有故障代码的表


在您的情况下,
fs\u fault
似乎包含下载的所有故障。这可能是意外行为的情况吗?

左侧外部联接选择第一个表中的所有内容以及第二个表中的匹配行。第一个表似乎包含下载尝试。因此,来自“from”的结果包括所有下载尝试

但是,它不一定包含所有故障代码。发生的情况是,一个或多个符合条件的代码没有故障

您需要一个包含所有故障代码的表,以使其正常工作。这里我只是创建一个故障代码列表作为第一个表。我认为以下查询可以做到这一点:

SELECT thefaults.faultcode, f.downloadtimeid, d.downloadtime, count(*) as faultcount
FROM  (select 1000 as faultcode union all select 1100
      ) thefaults join
      fs_fault f
      on f.faultcode = thefaults.faultcode and
         f.statusid in (2, 4) left outer join
      download_time d
      ON f.downloadtimeid = d.id
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 

我承认:我正在使用SQL Server语法创建“故障”。

如果您希望按故障代码计数,这似乎是最简单的解决方案:

WITH fc(faultcode) AS (VALUES (1000,1100))
SELECT fc.faultcode, count(d.downloadtimeid) as faultcount 
  FROM fc
  LEFT JOIN (fs_fault f ON f.faultcode = fc.faultcode
                       AND f.statusid IN(2, 4)
  JOIN download_time d ON d.id = f.downloadtimeid
                      AND d.bunoid = 166501
                      AND d.downloadtime::date BETWEEN date '2011-04-11'
                                                   AND date '2011-05-01')
  GROUP BY fc.faultcode
  ORDER BY fc.faultcode

请注意,我保留了您的条件,如果故障没有正确的statusid或bunoid,则不计算故障。我有点担心日期选择可能没有按照你的想法进行,所以我建议了另一种选择。如果您使用的是没有时区的时间戳,那么即使这样也可能做不到您想要的,但这是另一回事。我还添加了一个
orderby
子句,因为您可能不希望结果的顺序不一致;如果没有这个子句,它可能会也可能不在
分组顺序中,而且可能会在没有警告的情况下发生变化。

我给出我的答案,因为我对其他答案有很大的怀疑。你必须小心过滤器的要求。记住,where子句在联接之后运行。因此,如果where子句中有任何引用非外部联接表的筛选器要求,则(在许多情况下)已使外部联接无效。因此,对于sql来说,最简单的解决方案似乎是要么使用正确的join,要么适当地移动表名,然后将筛选条件移出where子句,移到join子句中

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_故障的过滤器要求在哪里并不重要。(无论如何,您的SQL引擎都将改变这一切)


编辑:这是一个关于join子句和where子句的筛选演示。

您分析过数据吗?我怀疑这是PostgreSQL内部的问题……请提供表结构和示例数据,好吗?
downloadtime d LEFT OUTER JOIN fs\u fault f ON f.downloadtime id=d.id
has
download\u time
作为左表,而不是
fs\u fault
。联接条件与联接中的左表或右表无关。如果故障代码没有关联的下载时间,它将被where子句.Oops过滤掉。通过添加括号来强制联接的求值顺序,修复了此问题。谢谢@JayC在他的回答中就
WHERE
子句与
JOIN
条件提出了一个很好的观点。如前所述,如果条件排除了特定faultcode的唯一行,faultocde将不会出现。通过移动条件修复。如果faultcode没有相关的下载时间,它将被where子句过滤掉。我们假设这是提问者想要的。关于
where
子句与
JOIN
条件的对比,您是对的。关于这一点,我已经确定了我的答案。不过,我想你还没有回答过他的问题,即即使没有出现所需的故障代码,如何让其显示。谢谢大家:我将投票归功于所有响应者,因为我从他们身上学到了一些东西。然而,杰克,你的是最近的。唯一的更改是将“f.faultcode IN(10001100)”移动到where子句。执行此操作时,将显示正确的故障代码。谢谢,杰克!我无法让小提琴工作。我正在使用IE 7.0.5730.13CO,因为我在工作。我必须在我通常使用Chrome浏览器的家里试用。