SQL组通过排序结果

时间:2018-08-06 13:49:41

标签: sql group-by

我的桌子看起来像这样:

----------------------------------------------------------
| ID | League | Reference | Created_at           | Value |
----------------------------------------------------------
| 1  | Test   | Exa       | 2018-08-05 11:52:30  | 12.00 |
----------------------------------------------------------
| 2  | Test   | Alch      | 2018-08-05 12:52:30  | 9.12  |
----------------------------------------------------------
| 3  | Test   | Chrom     | 2018-08-05 12:50:30  | 6.00  |
----------------------------------------------------------
| 4  | Test   | Chrom     | 2018-08-05 10:50:30  | 2.00  |
----------------------------------------------------------

每隔5分钟我会在表上保存一个参考值

我想检索每个参考的值(按created_at DESC排序的最新值。目前,在我的代码中,我仅遍历参考[exa, alch, ...]的数组,并执行以下查询(针对每个联赛):

SELECT created_at, league, value, reference
FROM currency
WHERE league = ? AND reference = ?
ORDER BY created_at DESC
LIMIT 1

基本上,我对每个联赛的每个引用执行该查询,导致执行了很多查询,并导致服务器上的响应时间很高...

预期结果应该是,从X联赛收集每个参考值,但仅收集最新插入值(created_at DESC),每种参考类型(例如,exa,alch,...) )将具有不同的created_at值(可能等于其他参考类型)

我尝试使用group_by完全没有成功,因为我只会得到表格的第一个结果(较旧的结果):

SELECT created_at, league, value, reference
FROM currency
WHERE league = ? AND reference IN ('exa', 'alch', ...)
GROUP BY created_at DESC

我认为这种group_by方法自从查询每个联赛以来会更快,但是我总是得到较旧的结果,而不是最近创建的结果...

5 个答案:

答案 0 :(得分:1)

具有一个子查询,该查询返回每个联赛的最大created_at值。 JOIN得到的结果:

select c1.*
from currency c1
join (select league, max(created_at) max_created_at
      from currency
      group by league) c2
  on  c1.league = c2.league
  and c1.created_at = c2.max_created_at

答案 1 :(得分:1)

您可以将subquerylimit子句一起使用:

select c.*
from currency c
where id = (select c1.id
            from currency c1
            where c1.league = c.league and
                  c1.Reference = c.Reference -- might be you need this also
            order by c1.created_at desc
            limit 1
           );

答案 2 :(得分:1)

尝试以下查询-:

with cte as
(
select created_at, league, value, reference,ROW_NUMBER() over (partition by league,reference  order by   Created_at desc) rn 
from currency
)select * from cte where rn=1

SQL Server

答案 3 :(得分:1)

此查询似乎更有效,您可以在此处查看小提琴:http://sqlfiddle.com/#!9/2b2dfe/8

如果生产中仍有问题,请检查索引。

SELECT
  currency.ID,
  currency.League,
  currency.Reference,
  currency.Created_at,
  currency.Value
 FROM
   currency
JOIN (  
SELECT
  League,
  Reference,
  MAX(Created_at) AS Created_at
 FROM
   currency
 GROUP BY
   League,
   Reference
 ) AS a
 ON
   currency.League = a.League
   AND currency.Reference = a.Reference
   AND currency.Created_at = a.Created_at

答案 4 :(得分:0)

使用过滤器:

select c.*
from currency c
where c.created_at = (select max(c2.created_at)
                      from currency c2
                      where c2.league = c.league
                     );