【问题标题】:How to get the top group from sqlite query?如何从 sqlite 查询中获取顶级组?
【发布时间】:2018-06-08 23:39:54
【问题描述】:

我正在使用 sqlite chinook 数据库,并遇到了这种情况: db 代表一个音乐商店,其中invoices 表链接到customers

Invoices 表有一个total 列,我可以使用sum() 对来自customers 表的country 分组进行聚合。

SELECT 
    c.country,
    sum(i.total) totalspent,
    c.firstname,
    c.lastname

FROM 
    invoices i
    left join customers c on c.customerid= i.customerid

group by
    c.country,
    c.firstname,
    c.lastname

order by 2 desc

这将输出如下内容:

.---------------------------------------------.
| Country  | totalspent | firstname | lastname |
|----------------------------------------------|
| Czech R. | 49.62      |  Helena   |  Holy    |
| USA      | 47.62      |  Richard  | Cunning  |
| Chile    | 46.62      |  Luis     | Rojas    |
| Hungary  | 45.62      |  Ladislav | Kovac    |
| Ireland  | 45.62      |  Hugh     | O'Reilly |
| USA      | 43.62      |  Julia    | Barnett  |
...
...

您会注意到表格按totalSpent 降序排列。这将导致来自同一国家/地区的人由于花费了多少而以不同的顺序出现。

我怎样才能只获得每个国家/地区的前 1 行? 我尝试按每个国家/地区分组total 中的select max(),但没有成功。

这是我的尝试:

select 
  ...
  ...
where
    sum(i.total) in (select max(sm) 
                     from ( select 
                                  sum(ii.total) sm 
                             from 
                                  invoices ii left join customers cc 
                                     on cc.customerid = ii.customerid 
                             where cc.country = c.country ))


 ...
 group by
    ...

但这也没有用。

必须有一种更直接的方法来仅从结果行中选择排名靠前的国家/地区。

【问题讨论】:

    标签: sql sqlite aggregate-functions


    【解决方案1】:

    您可以使用 CTE:

    with ic as (
          select c.country, sum(i.total) as totalspent, c.firstname, c.lastname
          from invoices i left join
               customers c
               on c.customerid = i.customerid
          group by c.country, c.firstname, c.lastname
         )
    select ic.*
    from ic
    where ic.totalspent = (select max(ic2.totalspent) from ic ic2 where ic2.country = ic.country);
    order by 2 desc
    

    【讨论】:

    • 这正是我获得所需输出所需要的,同时保持查询易于准备和高效。
    【解决方案2】:

    SQLite 没有窗口函数。

    这只是一种方法,请检查它是否适合您的场景:

    假设这是您当前的结果:

    sqlite> create table c ( i int, p varchar(100), c varchar(100));
    sqlite> insert into c values
       ...> ( 100, 'pedro', 'USA'),
       ...> ( 120, 'marta', 'Spain'),
       ...> (  90, 'juan',  'USA' ),
       ...> ( 130, 'laura', 'Spain' );
    

    那么,查询可能是:

    sqlite> select c.*
       ...> from c inner join
       ...>  ( select c, max(i) as i from c group by c) m 
       ...> on c.c = m.c and c.i=m.i;
    

    在子查询中,我们得到每个国家的最大值。

    结果:

    100|pedro|USA
    130|laura|Spain
    

    注意在您的情况下,您应该从您的选择中进行选择。

    【讨论】:

      猜你喜欢
      • 2011-03-19
      • 2017-05-05
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 2018-02-23
      相关资源
      最近更新 更多