9

我有一个表,我试图从中检索每种证券的最新位置:

桌子:

我创建表的查询: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 |
+-------+----------+------------+

我一直在搞乱基于此页面的查询版本,但我似乎无法得到我正在寻找的结果。

这是我一直在尝试的:

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 必须与最大购买日期一起返回。

4

5 回答 5

20

您可以使用此查询。您可以在 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-小提琴链接

于 2014-04-25T06:36:34.597 回答
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

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

于 2013-03-04T21:39:04.413 回答
5

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

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

请注意,这比bluefeet 的答案要快,但不显示 ID。

于 2013-03-04T21:31:39.680 回答
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 ) ;
于 2013-03-04T23:51:34.547 回答
1
select security, max(buy_date) group by security from positions;

是您获得每种证券的最大购买日期所需的全部内容(当您大声说出您想要从查询中得到什么并包含短语“for each x”时,您可能想要在 x 上进行分组)

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

于 2013-03-04T21:29:53.033 回答