交叉加入查询

时间:2013-01-16 16:11:54

标签: sql oracle

重新翻译我原来的帖子以进一步澄清。

我目前有以下表格:

Product_Ref

  • product_id
  • PRODUCT_NAME

产品

  • PRODUCT_ID
  • so_date(日期)
  • TOTAL_SALES

日历

  • dt(日期字段,每行代表过去/未来10年的一天)

我希望制作一份报告,告诉我过去6个月内销售的产品数量(基于SYSDATE),报告应该是过去6个月中每天的每一个组合每种可能的product_id格式为:

产品ID |日期|总销售额

如果我假设产品表中有0个条目(即没有销售),我仍然期望完整的报告输出,但它会显示6个月的零数据,即

1 | 2012-01-01 | 0
2 | 2012-01-01 | 0
3 | 2012-01-01 | 0
1 | 2012-01-02 | 0
2 | 2012-01-02 | 0
3 | 2012-01-02 | 0
…

这可以假设product_reference表中有3个产品 - 我的原始查询(如下所示)是我10岁的首发,但不知道从哪里开始。

SELECT products.product_id, calendar.dt, products.total_sales
FROM products RIGHT JOIN calendar ON (products.so_date = calendar.dt)
WHERE calendar.dt < SYSDATE AND calendar.dt >= ADD_MONTHS(SYSDATE, -7)+1
ORDER BY calendar.dt ASC, products.product_id DESC;

3 个答案:

答案 0 :(得分:1)

线索就在于问题 - 你正在寻找一个交叉加入。

SELECT products.product_id, calendar.dt, products.total_sales
FROM Product_Ref
CROSS JOIN calendar 
LEFT JOIN products ON products.so_date = calendar.dt 
                    AND products.product_id = Product_Ref.product_id
WHERE calendar.dt < SYSDATE AND calendar.dt >= ADD_MONTHS(SYSDATE, -7)+1
ORDER BY calendar.dt ASC, products.product_id DESC;

我最初对你的表名感到困惑,其中“Product”实际上意味着“sale”和“Product_Ref”是一种产品!

这与我曾发布here时使用CROSS JOIN的示例非常类似。

答案 1 :(得分:0)

假设您所需的输出仅与产品日期与日历表中的日期相匹配,则应使用INNER JOIN

SELECT c.dt, p.product_id, p.total_sales
FROM calendar c
INNER JOIN products p on c.dt = p.so_date
WHERE c.dt < SYSDATE and c.dt >= ADD_MONTHS(SYSDATE,-7)+1
ORDER BY c.dt ASC, p.product_id DESC;

CROSS JOIN会产生产品表和日历表中每个组合的结果,因此不需要使用ON

- 编辑

见下面的编辑(UNTESTED):

SELECT PR.Product_ID, C.dt, P.TotalSales
FROM Calendar C 
   CROSS JOIN Product_Ref PR 
   LEFT JOIN Product P ON P.Product_Id = PR.Product_Id and p.so_date = c.dt
WHERE c.dt < SYSDATE and c.dt >= ADD_MONTHS(SYSDATE,-7)+1
ORDER BY c.dt ASC, p.product_id DESC;
祝你好运。

答案 2 :(得分:0)

据我所知,如果没有销售,你想要的是没有结果吗?

所以,我认为您只需要将 RIGHT JOIN 更改为 INNER JOIN

通过RIGHT连接,如果JOIN表中有寄存器且FROM表中没有,它将从JOIN表中返回数据,并在引用FROM表的列中使用NULL值。

通过INNER加入,只要您在两个表中都有匹配的数据,就会得到结果。

希望我理解得很好并且有所帮助。