0

我有一张桌子

ORD_DATE ORD_ID ORD_REF ORD_TYPE1 ORD_TYPE2 产品编号 PRODQUAL 价格
2020-09-01 101 101 命令 命令 456 F 555
2020-09-02 102 101 会议 命令 456 F 555
2020-11-30 103 102 命令 命令 123 ķ 444
2020-12-01 104 102 会议 命令 123 ķ 444
2020-12-01 105 103 命令 命令 123 ķ 444
2020-12-01 106 104 命令 命令 123 ķ 333
2020-12-02 107 104 会议 命令 123 ķ 333
2020-12-08 108 104 会议 返回 123 ķ -333
2020-12-01 109 105 命令 命令 123 F 222
2020-12-02 110 105 会议 命令 123 F 222

和一张桌子:

ORD_DATE PROD_NUMBER 产品质量
2020-12-01-00.00.00.000000 123 ķ
2020-12-01-00.00.00.000000 123 大号
  • 在表 t 中是每天的所有销售额。
  • 销售有 2 个阶段:首先,当客户购买某物时生成订单(“ORDER”/“ORDER”)。然后它会被确认是在第二天还是通常在接下来的几天内(“CONF”/“ORDER”)。如果客户将产品退回,则为退货(“CONF”/“RETURN”)。

表 s 中是“二手”产品。

  • 如果产品在该表中,则表示表 t 中的所有销售额
ORDER_TYPE_1 = "ORDER"
AND ORDER_TYPE_2 = "ORDER"
AND t.ORD_DATE >= s.ORD_DATE
AND t.PROD_NUMBER = s.PROD_NUMBER
AND t.PROD_QUAL = s.PROD_QUAL

算作“二手”。

我需要从 2021 年和第 12 个月确认的所有“二手”销售额的总和。但只有带有 CONF/ORDER 或 CONF/RETURN 的行才应该在计算中。为此,我在表 t 中有 CAL_YEAR 和 CAL_MONTH(为减少混乱而省略)。

从表 t 中,只有 ORDER_REF 105 匹配,并且总和为 0,因为只有这 2 行很重要:

| 2020-12-02 | 107    | 104     | CONF      | ORDER     | 123     | K        | 333
| 2020-12-08 | 108    | 104     | CONF      | RETURN    | 123     | K        | -333

到目前为止我的代码:

SELECT SUM(PRICE)
FROM t
--
LEFT JOIN s
ON t.PRODNUM = s.PRODNUM
AND t.PRODQUAL = s.PRODQUAL
AND (SELECT ORD_DATE FROM t WHERE ORDER_TYPE_1 = 'ORDER' AND ORDER_TYPE_2 = 'ORDER') >= s.ORD_DATE
--
WHERE CAL_YEAR = 2021
AND CAL_MONTH = 12
AND ORDER_TYPE_1 = 'CONF'
AND ORDER_TYPE_2 IN ('ORDER', 'RETURN')
--
GROUP BY PRICE
;

SQL-Error:“单行子查询返回多于一行

我的问题是将 LEFT JOIN 限制为 ORDER/ORDER(以便 ORDER_REF 105 进入),但仅使用 CONF/ORDER 和 CONF/RETURN 作为总和(以便 ORDER_REF 102 退出)。

任何人都可以帮忙吗?

4

1 回答 1

0

我能想到的最简单的方法是进行自联接,在其中加入别名为 CONF/ORDER 和 CONF/RETURN 行的表 t 的第二个副本,同时用于 ORDER/ORDER 行。t2t

SELECT SUM(t2.PRICE)
FROM t
--
INNER JOIN t t2
ON t2.ORD_REF = t.ORD_REF
AND t2.ORDER_TYPE_1 = 'CONF'
AND t2.ORDER_TYPE_2 IN ('ORDER', 'RETURN')
-- 
LEFT JOIN s
ON t.PRODNUM = s.PRODNUM
AND t.PRODQUAL = s.PRODQUAL
AND t.ORD_DATE >= s.ORD_DATE
--
WHERE t.CAL_YEAR = 2021
AND t.CAL_MONTH = 12
AND t.ORDER_TYPE_1 = 'ORDER'
AND t.ORDER_TYPE_2 = 'ORDER'
;

如果您需要提高效率,您可以使用分析/窗口函数将总价格从 CONF 行拉到 ORDER/ORDER 行中作为新列。这样它只会查询t一次表而不是两次。

SELECT SUM(t2.order_price_sum)
FROM (select t.*, 
            sum(case when ORDER_TYPE_1 = 'CONF' 
                          AND ORDER_TYPE_2 IN ('ORDER', 'RETURN') 
                     then t.price 
                     else 0 end) over (partition by ord_ref) as order_price_sum
            from t) t2
--
LEFT JOIN s
ON t2.PRODNUM = s.PRODNUM
AND t2.PRODQUAL = s.PRODQUAL
AND t2.ord_date >= s.ORD_DATE
--
WHERE CAL_YEAR = 2021
AND CAL_MONTH = 12
AND ORDER_TYPE_1 = 'ORDER'
AND ORDER_TYPE_2 = 'ORDER'
;
于 2021-12-22T20:34:33.480 回答