重新翻译我原来的帖子以进一步澄清。
我目前有以下表格:
Product_Ref
产品
日历
我希望制作一份报告,告诉我过去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;
答案 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加入,只要您在两个表中都有匹配的数据,就会得到结果。
希望我理解得很好并且有所帮助。