SQL:在选择不同的行时按一个字段中的最小值进行分组

时间:2013-09-10 17:17:57

标签: sql group-by max distinct min

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

id | record_date | other_cols
18 | 2011-04-03  | x
18 | 2012-05-19  | y
18 | 2012-08-09  | z
19 | 2009-06-01  | a
19 | 2011-04-03  | b
19 | 2011-10-25  | c
19 | 2012-08-09  | d

对于每个id,我想选择包含最小record_date的行。所以我得到了:

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

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

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

10 个答案:

答案 0 :(得分:68)

这样的东西
SELECT mt.*,     
FROM MyTable mt INNER JOIN
    (
        SELECT ID, MIN(Record_Date) MinDate
        FROM MyTable
        GROUP BY ID
    ) t ON mt.ID = t.ID AND mt.Record_Date = t.MinDate

这将获取每个ID的最小日期,然后根据这些值获取值。只有重复的唯一时间是相同ID的最小record_dates重复。

答案 1 :(得分:12)

我可以通过在中执行此操作来获得预期结果:

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

这对你有用吗?

答案 2 :(得分:6)

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

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

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

答案 3 :(得分: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

答案 4 :(得分:1)

我想在这里添加一些其他答案,如果你不需要第一个项但是说第二个数字,例如你可以在子查询和基础中使用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具有相同的值。如果需要,您还可以使用逗号分隔多个列

答案 5 :(得分:0)

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

\s*((?1))

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

答案 6 :(得分:0)

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

SELECT
    WORKORDERNUM,
    MIN(DATE)
FROM
    WORKORDERS
WHERE
    DATE >= to_date('2015-01-01','YYYY-MM-DD')
GROUP BY
    WORKORDERNUM

答案 7 :(得分:0)

如果record_date在组中没有重复项:

从过滤开始考虑它。简单地从当前组中获得(WHERE)一(MIN(record_date))行:

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中的2分钟以上的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_id个:#1和#4

答案 8 :(得分:0)

miu <- integrate(func, lower=0, upper=inf)
print(miu)

答案 9 :(得分:0)

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

此代码消除重复的 record_date,以防有相同的 ids 和相同的 record_date
如果您想要重复,请删除最后一行 GROUP BY p.id