涉及的 SQL 查询问题(我猜是 SUM、Group By、Order by?也许是总数,甚至计数)

Posted

技术标签:

【中文标题】涉及的 SQL 查询问题(我猜是 SUM、Group By、Order by?也许是总数,甚至计数)【英文标题】:SQL Query Problem Involving (SUM, Group By, Order by, I guess? and maybe total, or even count) 【发布时间】:2021-03-01 13:57:08 【问题描述】:

通过 SQL 查询,找出总交易额最高的前 5 个行业,它们是哪个行业?以及该行业的店铺数量?

我的 SQL 数据如下所示:

Store Name Industry Transaction Value
Ace A 196
Ace A 193
Area A 168
Apple A 165
Boy B 145
Boy B 143
Bull B 136
Bread B 131
Cat C 116
Cat C 106
Cake C 104
Candy C 102
Dog D 101
Dog D 92
Door D 80
Daddy D 75
Egg E 70
Egg E 67
Earl E 66
Eagle E 61

仅供参考,最高交易额前5名是:

No. Store Name Industry Total Transaction Value
1 Ace A 389
2 Boy B 288
3 Cat C 222
4 Dog D 193
5 Area A 168

SQL 查询结果应如下所示:

Industry No. of Stores
A 2
B 1
C 1
D 1
E 0

【问题讨论】:

您使用的是哪个数据库? @Linker 我正在使用 Snowflake SQL 数据库 只有显示结果数据,任务才会变得清晰。 “总交易价值”是指每个商店名称和行业。当然,每个商店名称和行业都转换为GROUP BY store_name, industry。但前 5 名最高?这是此类任务的另一个问题。如果有关系怎么办,例如#5 = 168 和 #6 = 168。那么我们要显示所有六行吗?还是只有四个?或者选择两个捆绑行中的一个,因此只显示五行,而最后一行是任意选择的? 然后结果中有5个行业。这只是碰巧出现在表格中的所有行业吗?或者是否有一个包含我们应该作为参考的所有行业的行业表? @ThorstenKettner 1)刚才一个人发布了第一个答案,但他删除了它,不知道为什么。我立即尝试了它并且它有效,但没有显示 E 行业有 0 个商店。 2)我想有关系的情况不太可能,因为我正在处理的实际数据是,前 5 名至少为 12,345,678.90 美元。如果确实发生了这种情况,我想包括关系,结果显示为 6行。如果你碰巧知道怎么做,请告诉我。 【参考方案1】:
select a.industry, sum(case when b.name is null then 0 else 1 end) as no 
from
    (select distinct industry from transactions ) a
left join
    (select name, industry 
    from transactions 
    group by name, industry
    order by sum(transaction_vaule) desc limit 5) b
on a.industry = b.industry
group by a.industry
order by a.industry

【讨论】:

好答案。但是一些解释性文字会让它变得更好:-) sum(case when b.name is null then 0 else 1 end) 通常简单地写成count(b.name) 顺便说一句。【参考方案2】:

我想我有一个适合你的解决方案。请检查我的代码,我使用了 Common Table Expression ,CASE,SUMgroup by =>

WITH CTE AS
(
SELECT industry, SUM(TransactionValue) AS Transaction_Value, 
COUNT(StoreName) AS StoreCount  FROM MYTable
    GROUP BY StoreName,industry
    ORDER BY SUM(TransactionValue) DESC
    Limit 5
)
SELECT T1.industry,
       SUM((CASE WHEN c.industry IS NULL THEN 0
       ELSE 1 END)) as CT
FROM
(SELECT DISTINCT Industry FROM MYTable) AS T1
LEFT JOIN CTE as c ON T1.industry=c.industry
GROUP BY  T1.industry

注意:子查询不是最佳实践,但在您的情况下,我认为不会有性能问题。另外,请检查代码,因为我没有安装 Snowflake SQL 数据库,所以可能会出现一些语法错误 .

【讨论】:

【参考方案3】:

要获得确定性结果,您必须了解关系。假设前 9 个结果是

Cat/A/600、Dog/A/500、Cat/B/500、Dog/B/400、Cat/C/300、Dog/C/300、Cat/D/300、Dog/D/200、Cat/电子/100

哪个是前五? Cat/C/300 或 Dog/C/300 或 Cat/D/300?还是一个都没有?如果我们任意选择一行(LIMIT 5FETCH FIRST 5 ROWS ONLY),我们更喜欢一个行业而不是另一个行业。

在标准 SQL 中,我们有子句 FETCH FIRST 5 ROWS WITH TIES,但很遗憾,雪花没有这个功能。然而,它确实具有DENSE_RANK。它对我的样本行进行排序:

#1:猫/A/600 #2:狗/A/500 #2:猫/B/500 #3:狗/B/400 #4:猫/C/300 #4:狗/C/300 #4:猫/D/300 #5:狗/D/200 #6:猫/E/100

因为前五个值分别是 600、500、400、300 和 200。

查询:

select industry, count(case when rnk <= 5 then 1 end) as stores
from
(
  select industry, dense_rank() over (order by sum(transaction_value) desc) as rnk
  from mytable
  group by store_name, industry
) ranked
group by industry
order by industry;

如果你只想展示***行业:

select industry, count(*) as stores
from
(
  select industry, dense_rank() over (order by sum(transaction_value) desc) as rnk
  from mytable
  group by store_name, industry
) ranked
where rnk <= 5
group by industry
order by industry;

【讨论】:

SQL 编译错误:位置 0 处的语法错误第 2 行意外 '('。 哦。括号'('之前缺少'FROM',您的解决方案也解决了我的问题。谢谢 哦,对了,我忘记了 FROM 关键字。对于那个很抱歉。感谢您发现错误。我很高兴我们的查询对您有用。我希望你能从他们身上学到一两件事:-)

以上是关于涉及的 SQL 查询问题(我猜是 SUM、Group By、Order by?也许是总数,甚至计数)的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 中的 XQuery 对零值进行 SUM

「MySQL」- 复杂的SQL查询语句

SQL结构化查询语言分类介绍

关于SQL中两张表联合sum和group by的查询问题

SQL单表查询

在实体框架 C# 中使用 Lambda 编写多个 Sum() SQL 查询