PostgreSQL - 获取空值的记录

时间:2012-09-17 12:20:22

标签: postgresql

我正在尝试获取一个查询,该查询会显示在90天内没有销售任何东西的分销商,但我得到的问题是NULL值。似乎PostgreSQL忽略了空值,即使我查询它显示它(或者我可能以错误的方式做到)。

假设有1000个经销商,但有了这个查询,我只得到1个经销商,但应该有更多的经销商没有出售任何东西,因为如果我写SQL查询显示最后以任何金额出售的经销商90天,它显示大约500.所以我想知道其他499在哪里?如果我理解正确,那些其他499,没有任何销售,所以所有记录都是空的,不会在查询中显示。

有没有人知道如何让它显示一个表的空值,而其他表是否为空? (比如合作伙伴表(res_partner)不是null,但是sale_order表(sales)或对象是null?(我也尝试过滤像so.id IS NULL,但是这样我得到空查询)

我的查询代码:

(
SELECT
    min(f1.id) as id,
    f1.partner as partner,
    f1.sum1
       FROM
    (
       SELECT
          min(f2.id) as id,
          f2.partner as partner,
          sum(f2.null_sum) as sum1
       FROM
    (
    SELECT
          min(rp.id) as id,
          rp.search_name as partner,
     CASE
       WHEN
             sol.price_subtotal IS NULL
       THEN
             0
       ELSE
             sol.price_subtotal
     END as null_sum
    FROM
          sale_order as so,
          sale_order_line as sol,
          res_partner as rp
    WHERE
    sol.order_id=so.id and
    so.partner_id=rp.id
    and
    rp.distributor=TRUE
    and
    so.date_order <= now()::timestamp::date
    and
    so.date_order >= date_trunc('day', now() - '90 day'::interval)::timestamp::date
    and 
    rp.contract_date <= date_trunc('day', now() - '90 day'::interval)::timestamp::date
    GROUP BY
    partner,
    null_sum
   )as f2
   GROUP BY
   partner
  ) as f1
WHERE
sum1=0
GROUP BY
partner,
sum1
)as fld

编辑:2012-09-18 11 AM。

我想我理解为什么Postgresql会像这样。这是因为时间间隔。它检查该inverval中是否存在任何非空值。所以它只找到一条记录,因为该记录的销售订单为零(它没有从零转换为零),而且只是跳过检查空值的部分。如果我删除时间间隔,那么我会看到所有经销商根本没有出售任何东西。但由于某种原因,由于时间间隔,它会停止检查空值并查看是否只有空值。

所以有人知道如何让它在给定的时间间隔内检查空值吗?..(确切地说是过去90天)

2 个答案:

答案 0 :(得分:2)

sum()min()等聚合会忽略NULL个值。这是SQL标准所要求的,我所知道的每个DBMS都是这样的。

如果您想将NULL值视为例如零,然后使用这样的东西:

sum(coalesce(f2.null_sum, 0)) as sum1

但据我了解你的问题和无效的查询,你实际上想要res_partner和销售表之间的外部联接。

这样的事情:

SELECT min(rp.id) as id,
       rp.search_name as partner,
       sum(coalesce(sol.price_subtotal,0)) as price_subtotal
FROM res_partner as rp 
  LEFT JOIN sale_order as so ON so.partner_id=rp.id and rp.distributor=TRUE
  LEFT JOIN sale_order_line as sol ON sol.order_id=so.id 
WHERE so.date_order <= CURRENT_DATE
  and so.date_order >= date_trunc('day', now() - '90 day'::interval)::timestamp::date
  and rp.contract_date <= date_trunc('day', now() - '90 day'::interval)::timestamp::date
GROUP BY rp.search_name

我不是100%确定我正确地理解了你的问题,但它可能会给你一个头脑。

答案 1 :(得分:0)

尝试命名子查询,并使用col.q1,col.q2等检索其列,以确保从哪个列查询/子查询处理。也许它有点简单,例如它将一些只包含NULL的行合并为一行?此外,至少出于调试目的,在每个查询/子查询的末尾添加count(*)以获得结果返回的隐式行数是很聪明的。很难猜到究竟发生了什么..