【问题标题】:grouping records by a field and submit a query on each group in sql按字段分组记录并在sql中对每个组提交查询
【发布时间】:2020-04-08 10:20:02
【问题描述】:

我有一张这样的桌子:

create table product_company (
    id int PRIMARY KEY,
    productName varchar(100),
    companyName varchar(100),
    price int
);

我想知道每家公司价格排名第二的产品名称。

例如,如果company1 有三个产品product1=30product2=50product3=15(分配显示该公司中每个产品的价格),那么product1 在@987654327 中的价格属性中排名第二@ 并且我想编写一个返回如下内容的查询:

company1 product1
company2 ...
...

我的意思是对于每家公司,我想知道该公司中价格排名第二的产品。 我不知道如何使用 group by 子句,因为 group by 通过聚合函数可以正常工作,但我不想要最高价格。

我想用标准的 sql 查询和子句编写这个查询,并且没有一些在某些 DBMS 中可能不起作用的特殊功能

【问题讨论】:

  • 你运行的是哪个版本的 MySQL?
  • 没关系。我可以使用 (limit offset,index) 但我不知道如何使用这样的东西并编写正确的查询

标签: mysql sql subquery greatest-n-per-group window-functions


【解决方案1】:

如果你运行的是 MySQL 8.0,你可以使用窗口函数dense_rank()

select *
from (
    select
        pc.*,
        dense_rank() over(partition by companyName order by price desc) rn
    from product_company pc
) t
where rn = 2

在早期版本中,一种解决方案是使用相关子查询进行过滤。但是你必须小心正确处理可能的顶级关系。应该这样做:

select pc.*
from product_company pc
where (
    select count(distinct pc1.price) 
    from product_company pc1 
    where pc1.companyName = pc.companyName and pc1.price > pc.price
) = 1

【讨论】:

  • 不使用dense_rank()这可能吗
  • 仅通过标准 sql 子句
  • mysql 5.7是版本
【解决方案2】:

带有 COUNT 的 EXISTS 也可以用于此

例如:

create table product_company (
    id int PRIMARY KEY AUTO_INCREMENT,
    productName varchar(100),
    companyName varchar(100),
    price decimal(16,2)
);
insert into product_company 
(productName, companyName, price) values
 ('product 1', 'odd org', 9)
,('product 2', 'odd org', 15)
,('product 3', 'odd org', 11)
,('product 4', 'odd org', 17)
,('product 5', 'even inc.', 18)
,('product 6', 'even inc.', 12)
,('product 7', 'even inc.', 16)
,('product 8', 'even inc.', 14)
;
select *
from product_company t
where exists
(
  select 1
  from product_company t2
  where t2.companyName = t.companyName
    and t2.price >= t.price
  having count(distinct t2.price) = 2
)
编号 |产品名称 |公司名称 |价钱 -: | :------------ | :------------ | ----: 2 |产品 2 |奇怪的组织| 15.00 7 |产品 7 |甚至公司| 16.00

db小提琴here

如果您想获得每家公司的前 2 名?
然后改HAVING子句

...
   having count(distinct t2.price) <= 2
...

【讨论】:

    猜你喜欢
    • 2010-09-27
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多