此 SQL 查询的解决方案?

Posted

技术标签:

【中文标题】此 SQL 查询的解决方案?【英文标题】:Solution for this SQL query? 【发布时间】:2010-04-05 17:11:38 【问题描述】:

假设你有这些表:

表名:推销员 字段:S_ID(主键)、名称

表名称:Region_1 字段:Reg_ID(主键)、S_ID(外键)、销售

表名称:Region_2 字段:Reg_ID(主键)、S_ID(外键)、销售

表名称:Region_3 字段:Reg_ID(主键)、S_ID(外键)、销售

表名称:Region_4 字段:Reg_ID(主键)、S_ID(外键)、销售

查询1:求出每个销售员在所有地区的总销售额。

查询 2:找出某个推销员在所有地区的总销售额。 (如果第一个解决了,我认为这很容易。:-))

【问题讨论】:

嗯...我认为您应该阅读数据库规范化。或者如果表格设计是问题的一部分,那么也许你的老师应该这样做。 到目前为止您尝试了什么,遇到了什么问题?不会只为你做作业。 目前尝试过的,你把它标记为家庭作业很好,但我们不会为你做...... 我对您的理解是否正确,您是否将每个区域放在单独的表中? 圣托莱多,他是家庭作业男孩——他肯定只需要打开大聚光灯,打开挡板就可以召唤曼老师吗? 【参考方案1】:

查询1:求出所有地区每个业务员的销售额。


用途:

   SELECT s.name,
          COALESCE(SUM(x.sales), 0) 
     FROM SALESMAN s
LEFT JOIN (SELECT r1.s_id,
                  r1.sales
             FROM REGION_1 r1
           UNION ALL
           SELECT r2.s_id,
                  r2.sales
             FROM REGION_2 r2
           UNION ALL
           SELECT r3.s_id,
                  r3.sales
             FROM REGION_3 r3
           UNION ALL
           SELECT r4.s_id,
                  r4.sales
             FROM REGION_4 r4) x ON x.s_id = s.s_id

查询 2:找出某个销售员在所有地区的总销售额。


将 WHERE 子句添加到上面的查询中:

   SELECT s.name,
          COALESCE(SUM(x.sales), 0) 
     FROM SALESMAN s
LEFT JOIN (SELECT r1.s_id,
                  r1.sales
             FROM REGION_1 r1
           UNION ALL
           SELECT r2.s_id,
                  r2.sales
             FROM REGION_2 r2
           UNION ALL
           SELECT r3.s_id,
                  r3.sales
             FROM REGION_3 r3
           UNION ALL
           SELECT r4.s_id,
                  r4.sales
             FROM REGION_4 r4) x ON x.s_id = s.s_id
    WHERE s.s_id = ?

...用销售人员的 s_id 值替换 ?

教训:UNION vs UNION ALL


UNIONUNION ALL 将允许您组合两个查询,但它们的列位置必须具有相同的数据类型。例如,假设查询一按以下顺序返回数据类型:

    整数 字符串

任何与第一个联合的后续查询都必须在相同的位置返回相同的数据类型。特别注意数据类型的事实——它不保证列内的数据。

UNIONs 的第二个问题是知道UNIONUNION ALL 之间的区别。 UNION 将删除存在的重复项(相当于使用 DISTINCT),这在给定场景中是不需要的。 UNION ALL不会删除重复项,因此速度更快。

【讨论】:

【参考方案2】:

这个设计似乎有点局限,但可能是老师想要引入一些新概念的方式,所以我们不要在这一点上争论太久。

继续阅读

UNION

UNION 用于合并结果 从多个 SELECT 语句到一个 单个结果集。

和GROUP BY and SUM 按特定销售人员分组,并对值求和。

【讨论】:

【参考方案3】:

我同意这是一个糟糕的数据库设计,但如果是家庭作业,我想这不是问题所在。我会考虑通过联合来解决这个问题——将 salesman 和所有区域表连接在一起,并对销售数字求和。

【讨论】:

@Col.Shrapnel,下一个问题可能是规范化表,因此您可以看到查询有多容易。 是的,我承认这是一个糟糕的设计,但我的一个晚辈就他的项目问了我这个问题。【参考方案4】:

查询 1:

SELECT S.S_ID, S.Name, 
  ((SELECT SUM(R1.sales) FROM Region_1 R1 WHERE S.S_ID = R1.S_ID) +
   (SELECT SUM(R2.sales) FROM Region_2 R2 WHERE S.S_ID = R2.S_ID) +
   (SELECT SUM(R3.sales) FROM Region_3 R3 WHERE S.S_ID = R3.S_ID) +
   (SELECT SUM(R4.sales) FROM Region_4 R4 WHERE S.S_ID = R4.S_ID)) Total
FROM Salesman S

或者:

SELECT S.S_ID, S.Name, (IFNULL(R1.sales, 0) + IFNULL(R2.sales, 0) + IFNULL(R3.sales, 0) + IFNULL(R4.sales, 0)) Total
FROM Salesman S LEFT JOIN Region_1 R1 ON S.S_ID = R1.S_ID
     LEFT JOIN Region_2 R2 ON S.S_ID = R2.S_ID
     LEFT JOIN Region_3 R3 ON S.S_ID = R3.S_ID
     LEFT JOIN Region_4 R4 ON S.S_ID = R4.S_ID;

或者...

创建更好的架构。如果业务扩展到其他国家,突然你有20万个地区,你会怎么做? : - )。

【讨论】:

这就是为什么讨厌子选择

以上是关于此 SQL 查询的解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

查询错误 SQL Compact Edition 3.5

如何提高子查询的性能或 sql 中子查询的替代方案

选择 SQL 查询时出现双倍结果 [重复]

AS400多成员文件SQL查询

sql2008提示“列名无效”,但是能正常查询

在sql中更新表[关闭]