1

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

假设有 1000 个分销商,但是通过这个查询我只得到 1 个分销商,但应该有更多没有销售任何东西的分销商,因为如果我编写 SQL 查询来显示过去 90 天内销售的任何数量的分销商,它显示大约 500。所以我想知道其他 499 在哪里?如果我理解正确,其他 499 没有任何销售,所以所有记录都是空的,并且不会在查询中显示。

有谁知道如何让它显示一个表的空值,而其他表不为空?(像合作伙伴表(res_partner)不为空,但sales_order表(销售)或对象为空?(我也尝试像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 点。

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

那么有谁知道如何让它在给定的时间间隔内也检查空值?..(准确地说是过去 90 天)

4

2 回答 2

2

聚合喜欢sum()并且min()确实忽略NULL值。这是 SQL 标准所要求的,我所知道的每个 DBMS 的行为都是如此。

如果您想将NULL值视为零,请使用以下内容:

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

但据我了解,您的问题和无效查询实际上需要 res_partner 和 sales 表之间的外部连接。

像这样的东西:

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% 确定我正确理解了您的问题,但它可能会给您一个先机。

于 2012-09-17T12:52:16.327 回答
0

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

于 2012-09-17T12:41:44.233 回答