繁体   English   中英

SQL 内连接 2 次

[英]SQL Inner Join 2 times

我想验证我写的 SQL 查询是否正确,或者可以根据下面给出的问题陈述进行改进。

表 td 包含客户购买的商品和订单状态。 我想编写一个查询来计算如果客户没有退回商品本可以赚取的额外资金以及相对于实际赚取的金额的百分比增长。

===== Table td =====
customer_id    qty    price_per_item($)  order_status
    1           3       2                 complete
    1           2       4                 cancelled
    2           2       3                 complete
    2           3       5                 complete
    3           5       2                 complete
    3           4       7                 cancelled

这是我写的 SQL 查询,但我不确定它是否正确。 请建议是否可以改进此查询。

select Actual_money.customer_id , Lost_money.lost_money , Actual_money.actual_money,
 Total_money.total_money , 100.0 * Lost_money.lost_money  / Actual_money.actual_money As percentage_increase
from  
       (select td.customer_id, sum(td.qty * td.price_per_item) lost_money               
                    from td
                   where td.order_status in 'cancelled'
                    group by td.customer_id) Lost_money
        inner join            

       (select td.customer_id, sum(td.qty * td.price_per_item) actual_money            
               from td
              where td.order_status in 'complete'
               group by td.customer_id) Actual_money

               on Lost_money.customer_id= Actual_money.customer_id
       inner join

        (select td.customer_id, sum(td.qty * td.price_per_item) total_money           
               from td
                             group by td.customer_id) Total_money  

                    on Actual_money.customer_id = Total_money.customer_id ;

不需要连接,条件总和更简单:

select customer_id, lost_money, actual_money, total_money, 
       100.0 * lost_money  / total_money as percentage_increase
  from (select customer_id, sum(qty * price_per_item) total_money, 
               sum(case order_status when 'cancelled' then qty * price_per_item end) lost_money,
               sum(case order_status when 'complete'  then qty * price_per_item end) actual_money
          from td group by customer_id)
  where lost_money is not null

数据库小提琴

这样你只扫描表一次。 最后一行消除没有取消订单的行,您也可以使用having子句来实现这一点。 我将公式稍微更改为lost/total ,这似乎提供了更多信息,但您可以继续使用。


编辑:解释原始查询的计划输出

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |     2 |   156 |    10  (40)| 00:02:53 |
|*  1 |  HASH JOIN            |      |     2 |   156 |    10  (40)| 00:02:53 |
|*  2 |   HASH JOIN           |      |     2 |   104 |     7  (43)| 00:01:53 |
|   3 |    VIEW               |      |     2 |    52 |     3  (34)| 00:00:52 |
|   4 |     HASH GROUP BY     |      |     2 |    90 |     3  (34)| 00:00:52 |
|*  5 |      TABLE ACCESS FULL| TD   |     2 |    90 |     2   (0)| 00:00:35 |
|   6 |    VIEW               |      |     4 |   104 |     3  (34)| 00:00:52 |
|   7 |     HASH GROUP BY     |      |     4 |   180 |     3  (34)| 00:00:52 |
|*  8 |      TABLE ACCESS FULL| TD   |     4 |   180 |     2   (0)| 00:00:35 |
|   9 |   VIEW                |      |     6 |   156 |     3  (34)| 00:00:52 |
|  10 |    HASH GROUP BY      |      |     6 |   234 |     3  (34)| 00:00:52 |
|  11 |     TABLE ACCESS FULL | TD   |     6 |   234 |     2   (0)| 00:00:35 |
------------------------------------------------------------------------------

建议查询:

----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     6 |   270 |     3  (34)| 00:00:52 |
|*  1 |  FILTER             |      |       |       |            |          |
|   2 |   HASH GROUP BY     |      |     6 |   270 |     3  (34)| 00:00:52 |
|   3 |    TABLE ACCESS FULL| TD   |     6 |   270 |     2   (0)| 00:00:35 |
----------------------------------------------------------------------------

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM