考虑一个表格T,列
我想在T上执行以下选择操作。
我想找到每个ID,这是最早购买的最贵的物品。
例如,如果表有三个记录,如下所示
ID Expense Date item
1 1000 10/20/2015 A
1 1000 10/21/2015 B
1 200 10/15/2015 C
它应该选择第一行。
我写了类似下面的内容,但它似乎无法正常工作
select T.id. T.expense, T.date, T.item
from T inner join
(select id, max(expense), min(date) from T
group by id) w on T.id = w.id and T.expense=w.expense and T.date=w.date;
请提出一些建议。 感谢
答案 0 :(得分:3)
尝试:
Select * from
(select row_number() over (partition by ID order by Expense desc, date asc)
RN, id, expense, date, item
from T)T
where RN=1
答案 1 :(得分:0)
编辑:这个答案是错误的,因为问题最初被标记为错误。我会编辑,但这里已经有另一个正确答案了。我要离开这里,因为它仍然展示了一个可行的解决方案,甚至可以在MySql上运行,但你应该真的投票给row_number()
解决方案。
考虑分三步完成此操作。首先,您需要了解最大费用。然后你需要找到相应的最小日期。最后,您可以获得与这些值匹配的整个记录。如果可以为ID匹配max和min的多个记录,则需要一个额外的步骤才能将其记录到单个记录中。
这些步骤中的每一步都可以通过子查询上的JOIN来完成:
select .*
FROM T tf --final
INNER JOIN (
select Td.ID, Td.expense, MIN(Td.date) MinDate
from T td --date
INNER JOIN (
select ID, MAX(expense) MaxExpense
from T te --expense
GROUP BY ID
) e on td.ID = e.ID AND td.expense = e.MaxExpense
GROUP BY ID, expense
) d ON tf.ID = d.ID AND tf.expense = d.expense AND tf.date = d.MinDate
同样,对于支持Window函数或APPLY运算符的数据库引擎来说,这要简单得多。这是一个可以用Sql Server编写的APPLY示例:
SELECT t1.*
FROM T t1
CROSS APPLY (
SELECT TOP 1 *
FROM T t2
WHERE t2.ID = t1.ID
ORDER BY t2.expense DESC, t1.Date
) a
这个功能得到了Sql Server,Oracle和Postgresql的支持,并且已经成为ansi标准的一部分已经超过10年了,而且这只是其中一个原因之一,MySql很快成为任何实际拥有者的笑话与多种数据库合作。
答案 2 :(得分:0)
在oracle,DB2或MS SQL中,您可以执行此操作以获取每行上的项目:
select T.id. T.expense, T.date, T.item,
max(T.expense) OVER (partition by T.id order by T.date asc) as m_expense
from T
这是为了获得符合这些标准的项目
SELECT id, expense, date, item
FROM (
select T.id, T.expense, T.date, T.item,
ROW_NUMBER() OVER (partition by T.id order by T.expense DESC, T.date asc) as rn
from T
) x
WHERE rn = 1
这使用了一个窗口函数。解释什么窗口函数的最佳方法是说它们完全符合您的需要:将函数应用于行的子集(窗口)。
答案 3 :(得分:0)
这应该有效
select t.id, t.expense, min(t.date), t.item
from (select max(expense) as expense, id from T group by id) x
join t
on t.id = x.id and t.expense = x.expense
group by t.id