分组最大值

时间:2013-03-04 21:27:57

标签: mysql sql

我有一张桌子,我正试图检索每个安检的最新位置:

表:

我创建表格的查询:SELECT id, security, buy_date FROM positions WHERE client_id = 4

+-------+----------+------------+
| id    | security | buy_date   |
+-------+----------+------------+
|    26 | PCS      | 2012-02-08 |
|    27 | PCS      | 2013-01-19 |
|    28 | RDN      | 2012-04-17 |
|    29 | RDN      | 2012-05-19 |
|    30 | RDN      | 2012-08-18 |
|    31 | RDN      | 2012-09-19 |
|    32 | HK       | 2012-09-25 |
|    33 | HK       | 2012-11-13 |
|    34 | HK       | 2013-01-19 |
|    35 | SGI      | 2013-01-17 |
|    36 | SGI      | 2013-02-16 |
| 18084 | KERX     | 2013-02-20 |
| 18249 | KERX     | 0000-00-00 |
+-------+----------+------------+

我一直在捣乱基于this page的查询版本,但我似乎无法得到我正在寻找的结果。

以下是我一直在尝试的内容:

SELECT t1.id, t1.security, t1.buy_date 
FROM positions t1
WHERE buy_date = (SELECT MAX(t2.buy_date)
                    FROM positions t2
                    WHERE t1.security = t2.security)

但这只会让我回头:

+-------+----------+------------+
| id    | security | buy_date   |
+-------+----------+------------+
|    27 | PCS      | 2013-01-19 |
+-------+----------+------------+

我正在尝试获取每个证券的最大/最新购买日期,因此每个证券的结果将有一行,最近的购买日期。非常感谢任何帮助。

编辑:必须以最大购买日期返回头寸的ID。

5 个答案:

答案 0 :(得分:16)

您可以使用此查询。您可以将时间缩短75%。我检查了更多的数据集。子查询需要更多时间。

SELECT p1.id, 
       p1.security, 
       p1.buy_date 
       FROM positions p1
left join
            positions p2
                on p1.security = p2.security
                   and p1.buy_date < p2.buy_date
      where 
      p2.id is null;

SQL-Fiddle link

答案 1 :(得分:9)

您可以使用子查询来获得结果:

SELECT p1.id, 
  p1.security, 
  p1.buy_date 
FROM positions p1
inner join
(
  SELECT MAX(buy_date) MaxDate, security
  FROM positions 
  group by security
) p2
  on p1.buy_date = p2.MaxDate
  and p1.security = p2.security

请参阅SQL Fiddle with Demo

或者您可以在WHERE子句中使用以下内容:

SELECT t1.id, t1.security, t1.buy_date 
FROM positions t1
WHERE buy_date = (SELECT MAX(t2.buy_date)
                  FROM positions t2
                  WHERE t1.security = t2.security
                  group by t2.security)

请参阅SQL Fiddle with Demo

答案 2 :(得分:5)

这是通过一个简单的组来完成的。您希望按证券分组并获得buy_date的最大值。 SQL:

SELECT security, max(buy_date) 
from positions
group by security

注意,这比bluefeet's answer快,但不显示ID。

答案 3 :(得分:3)

@bluefeet的答案有两种方法可以获得你想要的结果 - 第一种方法可能比你的查询更有效。

我不明白为什么你说你的查询不起作用。看起来很好,并返回预期的结果。在 SQL-Fiddle

进行测试
SELECT t1.id, t1.security, t1.buy_date 
FROM positions t1
WHERE buy_date = ( SELECT MAX(t2.buy_date)
                   FROM positions t2
                   WHERE t1.security = t2.security ) ;

如果在添加client_id = 4条件时出现问题,那么这是因为您只需在一个WHERE子句中添加它,而您必须在两者中添加它:

SELECT t1.id, t1.security, t1.buy_date 
FROM positions t1
WHERE client_id = 4
  AND buy_date = ( SELECT MAX(t2.buy_date)
                   FROM positions t2
                   WHERE client_id = 4
                     AND t1.security = t2.security ) ;

答案 4 :(得分:1)

select security, max(buy_date) group by security from positions;

是您获得每个安全性的最大购买日期所需的全部内容(当您大声说出您希望从查询中获得的内容并且您包含短语“for each x”时,您可能希望在x上分组)

当您使用group by时,您选择的所有列都必须是已按分组或聚合的列,因此,例如,如果您要包含ID,则可能必须使用子查询与之前的类似,因为似乎没有任何聚合可以合理地用于ID,而另一组则会给你太多的行。