【问题标题】:Convert multiple subqueries into a join (Join table to itself)将多个子查询转换为连接(将表连接到自身)
【发布时间】:2017-05-29 02:26:57
【问题描述】:
Table structures 

Table Products :
=============================================
ID | Store | Type | Cost | NetCost | 
=============================================
1  |102    | 0    |14.95 | 29.65
2  |103    | 1    |13.95 | 32.65
3  |104    | 2    |12.36 | 42.12
4  |105    | 3    |10.24 | 23.11
5  |106    | 4    |19.57 | 27.16
6  |102    | 0    |57.26 | 26.98
7  |103    | 3    |43.26 | 26.98
8  |104    | 4    |10.26 | 26.98
9  |105    | 1    |9.26  | 26.98
10 |105    | 5    |11.26 | 46.98


Same table separated into  two tables by Type
Premium products  : Type = ( 0, 1, 2 )
Basic products    : Type = ( 3, 4, 5 )

Table Products : Products with Type (0,1,2)
=============================================
ID | Store | Type | Cost | NetCost | 
=============================================
1  |102    | 0    |14.95 | 29.65
2  |103    | 1    |13.95 | 32.65
3  |104    | 2    |12.36 | 42.12
6  |102    | 0    |57.26 | 26.98
9  |105    | 1    |9.26  | 26.98

Table Products : Products with Type (3,4,5)
=============================================
ID | Store | Type | Cost | NetCost | 
=============================================
4  |105    | 3    |10.24 | 23.11
5  |106    | 4    |19.57 | 27.16
7  |103    | 3    |43.26 | 26.98
8  |104    | 4    |10.26 | 26.98
10 |105    | 5    |11.26 | 46.98

我想根据按商店分组的类型对所有产品的计数、成本和净成本求和。 结果应如下所示:

Table of totals: (B = Basic, P= Premium)
=================================================================
Store | B Cnt |B Cost | B NetCost | P Cnt | P Cost | P NetCost | 
=================================================================
102
103
104
105
106

我可以通过使用带有子查询的主查询来实现上述目的,是否还有更多 高效连接(将表连接到自身等)我能做到这一点将实现上面的表(总计)吗?

我将放在主查询中的子查询:

SELECT  
    count(*)
FROM 
    Products prod_prem
WHERE   
    (prod_prem.Type =  0 OR prod_prem.Type = 1 OR prod_prem.Type = 2)

SELECT  
    SUM(Cost),
FROM 
    Products prod_prem
WHERE   
    (prod_prem.Type =  0 OR prod_prem.Type = 1 OR prod_prem.Type = 2)

SELECT  
    SUM(NetCost)
FROM 
    Products prod_prem
WHERE   
    (prod_prem.Type =  0 OR prod_prem.Type = 1 OR prod_prem.Type = 2)


SELECT  
    count(*)
FROM 
    Products prod_basic
WHERE   
    (prod_prem.Type =  3 OR prod_prem.Type = 4 OR prod_prem.Type = 5)


SELECT  
    SUM(Cost),
FROM 
    Products prod_basic
WHERE   
    (prod_prem.Type =  3 OR prod_prem.Type = 4 OR prod_prem.Type = 5)


SELECT  
    SUM(NetCost)
FROM 
    Products prod_basic
WHERE   
    (prod_prem.Type =  3 OR prod_prem.Type = 4 OR prod_prem.Type = 5)

【问题讨论】:

    标签: sql sql-server sql-server-2008 join self-join


    【解决方案1】:

    您可以使用 Conditional Aggregation 在单个查询中执行此操作

    SELECT Store,
           [B Cnt] = Count(CASE WHEN Type IN ( 3, 4, 5 ) THEN 1 END),
           [B Cost] = Sum(CASE WHEN Type IN ( 3, 4, 5 ) THEN Cost ELSE 0 END),
           [B NetCost] = Sum(CASE WHEN Type IN ( 3, 4, 5 ) THEN NetCost ELSE 0 END),
           [P Cnt] = Count(CASE WHEN Type IN ( 0, 1, 2 ) THEN 1 END),
           [P Cost] = Sum(CASE WHEN Type IN ( 0, 1, 2 ) THEN Cost ELSE 0 END),
           [P NetCost] = Sum(CASE WHEN Type IN ( 0, 1, 2 ) THEN NetCost ELSE 0 END)
    FROM   Products
    GROUP  BY Store 
    

    【讨论】:

    • 这看起来更清晰易懂,我会在今天晚些时候尝试,如果成功,我会接受你的回答。格拉西亚斯。
    【解决方案2】:

    您应该有一个带有 IsPremium 位列的 ProductType 表。这样,当类型 6、7、8 出现时,您不必对代码进行可怕的容易出错的维护 - 您只需在类型表中插入新行。

    【讨论】:

    • 我不维护这些表,所以我必须照原样处理它们。
    • 明白了。如果这是在存储过程中,您可以将其创建为过程中的临时表,因此“高级”仅在 proc 中的一个位置而不是多个位置定义。可能比它的价值更麻烦,只是一个建议
    猜你喜欢
    • 2016-03-02
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多