联接中不存在行的SQL聚合函数

联接中不存在行的SQL聚合函数,sql,postgresql,Sql,Postgresql,我正在尝试为不存在的行查找一个SQL Get聚合为0,该行在特定年份使用下表的联接 Customers -> customerid, Name product -> prodcutid, price, name Sales -> productid,customerid,date, orders 我得到这个查询是为了找到某一年某一产品的现有订单的聚合,但我还想得到与其他产品在同一年内没有订购的产品: with cte as (select producid,custome

我正在尝试为不存在的行查找一个SQL Get聚合为0,该行在特定年份使用下表的联接

Customers -> customerid, Name
product -> prodcutid, price, name
Sales -> productid,customerid,date, orders
我得到这个查询是为了找到某一年某一产品的现有订单的聚合,但我还想得到与其他产品在同一年内没有订购的产品:

  with cte as (select producid,customerid,sum(orders) as s from sales 
  where date_part('year', date) = 2018
  group by productid,customerid)
  select a.name,b.name,(c.s * b.price) as sales
  from customers as a 
  join cte as c on a.prodcutid=c.productid
  join product as b on b.customerid=c.customerid; 

我通过上述查询能够获得的数据:

 -----------------------------------------------
 Product.name | Customer.name | Total_sale Value
 -----------------------------------------------
      TV       |   AUS        |  32000 (orders * price per product) 
      Fridge   |   AUS        |  4200 
      TV       |   US         |  320,000 
我想要的是2018年的数据:

 -----------------------------------------------
 Product.name | Customer.name | Total_sale Value
 -----------------------------------------------
      TV       |   AUS        |  32000 (orders * price per product) (if there was a sale then you should get a value else then it should be 0)
      Fridge   |   AUS        |  4200 
      Fridge   |   US         |  0 (as Customer US didnt order fridge at all)
      TV       |   US         |  320,000 
我试着遵循提供的相同解决方案
但无法得到答案,请原谅我的重复,但请让我知道我做错了什么。我是sql新手,因此请原谅我的重复。

注意:自发布此答案后,问题已被编辑,我不再100%确定所问的问题。

我正在尝试使用联接为不存在的行查找SQL Get聚合为0

从概念上讲,销售表将产品与客户联系起来

  • 有一种产品,而且总是有一种产品(因为你在看这个时好像“我对每一种产品都感兴趣,不管它卖不卖”)

  • 可能有一个客户(如果他们注册后从未购买过任何东西,那么他们可能是一个没有销售的客户)

  • 只有客户购买了产品才有销售(因此,销售中不会提到从未购买过任何产品的客户,我们只对已经销售或尚未销售的产品感兴趣)

因此,回答问题的关系图需要如下所示:

products -> sales -> customer
如果产品从未订购过,
products->sales
关系将中断,因此它需要是一个左连接以保留所有产品,并且仅当存在匹配的销售时才将销售与产品关联

sales->customer
不应该中断,可以是内部联接(如果您愿意首先联接),也可以是左联接(如果您不将其作为子查询执行)(如果您将其设置为immer-JOIN,则由于产品从未售出而为空的任何销售都将与客户不匹配,因此未售出的产品将从结果中消失)

因此,您需要如下查询:

SELECT ...
FROM
  products p
  LEFT JOIN sales s ON ...
  LEFT JOIN customer c ON ...
或者你需要

SELECT ...
FROM
  products p
  LEFT JOIN 
  (SELECT * FROM sales s INNER JOIN customer c ON ...) sc
如果使用第二种形式并在子查询中执行分组,可能会更简单,但在任何地方执行这些操作都很简单

针对从未销售过的产品引入的未销售的空值将参与SUM/AVG等,就好像它们是0一样



旁注,我不确定客户表对您所述的任何需求有何影响,可能可以省略它

您的代码在MySQL和SQL Server中都是正确的。我删除了这两个标记。请使用您真正使用的数据库进行标记。示例数据和所需结果也会澄清问题。您需要的表描述与您所显示的查询几乎无关。感谢@GordonLinoff正确更新了详细信息,但我还想获得与其他人在同一年内未订购的产品:-您能重新措辞吗?这没有多大意义您不想在两个ID上都使用CTE吗?只需使用左连接来覆盖该情况吗e该产品未订购。(您需要先加入
产品
)@shawnt00能否请您详细说明这两个ID,您是指2个CTE和左连接产品吗?我在销售和客户上尝试了CTE和连接,然后在产品上尝试了连接,但即使这样也没有产生所需的结果感谢@Caius Jard的回答,我相信我不清楚,让我做更多更新,我厌倦了这两个查询,我没有t success:`选择p.name,c.name,(p.price*sum(s.orders))作为产品的总销售额p.productid=s.productid左加入s.customerid=c.customerid和date_part('年',s.date)=2018年按p.name,c.name,p.price分组或选择p.name,sc.name,(p.price*sum(sc.orders))作为产品p左连接的总销售额(在s.customerid=c.customerid上从销售s内部连接客户c中选择*)在p.productid=s.productid和日期p左连接零件('year',sc.date)=2018 group by p.name,sc.name,p.price`@Satya我对你需要的东西一直有不同的解读。如果你想要所有产品和客户的组合,我相信这可以做到。谢谢@shawnt00,这太完美了。所以我必须在没有关系的地方进行交叉连接以获取数据并进行左外连接。我在错误的表上尝试了交叉连接再见,再次感谢。
with cte as (
    select productid, customerid, sum(orders) as s from sale
    where year(date) = 2018
    group by productid, customerid
)
select p.name, c.name, coalesce(s.s * p.price, 0) as sales
from product as p
    cross join customer as c
    left outer join cte as s on s.productid = p.productid
                           and s.customerid = c.customerid
with cte as (
    select productid, customerid, sum(orders) as s from sale
    where year(date) = 2018
    group by productid, customerid
)
select p.name, c.name, coalesce(s.s * p.price, 0) as sales
from product as p
    cross join customer as c
    left outer join cte as s on s.productid = p.productid
                           and s.customerid = c.customerid