83

这就是我想要做的。假设我有这张桌子:

key_id | id | record_date | other_cols
1      | 18 | 2011-04-03  | x
2      | 18 | 2012-05-19  | y
3      | 18 | 2012-08-09  | z
4      | 19 | 2009-06-01  | a
5      | 19 | 2011-04-03  | b
6      | 19 | 2011-10-25  | c
7      | 19 | 2012-08-09  | d

对于每个 id,我想选择包含最小记录日期的行。所以我会得到:

key_id | id | record_date | other_cols
1      | 18 | 2011-04-03  | x
4      | 19 | 2009-06-01  | a

我看到的解决这个问题的唯一方法是假设所有 record_date 条目都是不同的,但在我的数据中并非如此。使用带有两个条件的子查询和内部联接会给我一些 id 的重复行,这是我不想要的:

key_id | id | record_date | other_cols
1      | 18 | 2011-04-03  | x
5      | 19 | 2011-04-03  | b
4      | 19 | 2009-06-01  | a
4

10 回答 10

117

怎么样:

SELECT mt.*     
FROM MyTable mt INNER JOIN
    (
        SELECT id, MIN(record_date) AS MinDate
        FROM MyTable
        GROUP BY id
    ) t ON mt.id = t.id AND mt.record_date = t.MinDate

这将获取每个 ID 的最小日期,然后根据这些值获取值。唯一会出现重复的情况是同一 ID 的最小记录日期重复。

于 2013-09-10T17:25:35.590 回答
15

中执行此操作,我就可以达到您的预期结果:

 SELECT id, min(record_date), other_cols 
  FROM mytable
  GROUP BY id

这对你有用吗?

于 2013-09-10T17:33:28.017 回答
8

要获得每个类别中最便宜的产品,您可以在相关子查询中使用 MIN() 函数,如下所示:

    SELECT categoryid,
       productid,
       productName,
       unitprice 
    FROM products a WHERE unitprice = (
                SELECT MIN(unitprice)
                FROM products b
                WHERE b.categoryid = a.categoryid)

外部查询扫描 products 表中的所有行,并返回单价与相关子查询返回的每个类别中的最低价格匹配的产品。

于 2016-02-24T23:46:52.200 回答
3

我想在这里添加一些其他答案,如果您不需要第一项但说第二个数字,例如您可以在子查询中使用 rownumber 并以此为基础您的结果集。

SELECT * FROM
(
    SELECT
        ROW_NUM() OVER (PARTITION BY Id ORDER BY record_date, other_cols) as rownum,
        *
    FROM products P
) INNER
WHERE rownum = 2

这也允许您对子查询中的多个列进行排序,如果两个 record_dates 具有相同的值,这可能会有所帮助。如果需要,您还可以通过用逗号分隔多个列

于 2018-06-06T14:26:24.757 回答
1

这很简单:

select t2.id,t2.record_date,t2.other_cols 
from (select ROW_NUMBER() over(partition by id order by record_date)as rownum,id,record_date,other_cols from MyTable)t2 
where t2.rownum = 1
于 2016-11-08T17:21:35.947 回答
1
SELECT p.* FROM tbl p
INNER JOIN(
  SELECT t.id, MIN(record_date) AS MinDate
  FROM tbl t
  GROUP BY t.id
) t ON p.id = t.id AND p.record_date = t.MinDate
GROUP BY p.id

如果与 same相同,record_date则此代码将消除重复。 如果要重复,请删除最后一行。idsrecord_date
GROUP BY p.id

于 2021-08-03T07:02:40.550 回答
0

以下查询获取每个工作订单的第一个日期(在显示所有状态更改的表中):

SELECT
    WORKORDERNUM,
    MIN(DATE)
FROM
    WORKORDERS
WHERE
    DATE >= to_date('2015-01-01','YYYY-MM-DD')
GROUP BY
    WORKORDERNUM
于 2018-04-30T23:26:32.970 回答
0

这是一个老问题,但这对某人很有用在我的情况下,我不能使用子查询,因为我有一个大查询,我需要在我的结果上使用 min(),如果我使用子查询,数据库需要重新执行我的大查询询问。我正在使用 Mysql

select t.* 
    from (select m.*, @g := 0
        from MyTable m --here i have a big query
        order by id, record_date) t
    where (1 = case when @g = 0 or @g <> id then 1 else  0 end )
          and (@g := id) IS NOT NULL

基本上我订购了结果,然后放了一个变量,以便只获得每组中的第一条记录。

于 2016-05-05T21:03:39.297 回答
0
select 
    department, 
    min_salary, 
    (select s1.last_name from staff s1 where s1.salary=s3.min_salary ) lastname 
from 
    (select department, min (salary) min_salary from staff s2 group by s2.department) s3
于 2020-09-09T00:33:19.387 回答
0

如果record_date组内没有重复项:

将其视为过滤。MIN(record_date)简单地从当前组中获取(WHERE)一( )行:

SELECT * FROM t t1 WHERE record_date = (
                                 select MIN(record_date)
                                 from t t2 where t2.group_id = t1.group_id)

如果组内可能有 2+ 分钟record_date

  1. 过滤掉非最小行(见上文)

  2. 然后(AND)record_date在给定的group_id. 例如选择具有最小唯一键的那个:

                    AND key_id = (select MIN(key_id)
                                  from t t3 where t3.record_date = t1.record_date
                                              and t3.group_id    = t1.group_id)
    

所以

key_id | group_id | record_date | other_cols
1      | 18       | 2011-04-03  | x
4      | 19       | 2009-06-01  | a
8      | 19       | 2009-06-01  | e

将选择key_ids: #1和 #4

于 2020-06-22T10:42:13.870 回答