在C#中,它如下所示:
table
.GroupBy(row => row.SomeColumn)
.Select(group => group
.OrderBy(row => row.AnotherColumn)
.First()
)
Linq-to-SQL将其转换为以下T-SQL代码:
SELECT [t3].[AnotherColumn], [t3].[SomeColumn]
FROM (
SELECT [t0].[SomeColumn]
FROM [Table] AS [t0]
GROUP BY [t0].[SomeColumn]
) AS [t1]
OUTER APPLY (
SELECT TOP (1) [t2].[AnotherColumn], [t2].[SomeColumn]
FROM [Table] AS [t2]
WHERE (([t1].[SomeColumn] IS NULL) AND ([t2].[SomeColumn] IS NULL))
OR (([t1].[SomeColumn] IS NOT NULL) AND ([t2].[SomeColumn] IS NOT NULL)
AND ([t1].[SomeColumn] = [t2].[SomeColumn]))
ORDER BY [t2].[AnotherColumn]
) AS [t3]
ORDER BY [t3].[AnotherColumn]
但它与MySQL不兼容。
16条答案
按热度按时间7tofc5zh1#
我的回答只是基于你帖子的标题,因为我不懂C#,也不理解给定的查询。但在MySQL中,我建议您尝试SubSELECT。首先获取一组感兴趣的列的主键,然后从这些行中选择数据:
blpfk2vs2#
Here's another way you could try, that doesn't need that ID field.
Still I agree with lfagundes that you should add some primary key ..
Also beware that by doing this, you cannot (easily) get at the other values is the same row as the resulting some_colum, another_column pair! You'd need lfagundes apprach and a PK to do that!
332nm8kg3#
When I write
It works. IIRC in other RDBMS such statement is impossible, because a column that doesn't belongs to the grouping key is being referenced without any sort of aggregation.
This "quirk" behaves very closely to what I want. So I used it to get the result I wanted:
r1wp621o4#
Best performance and easy to use:
jum4pzuy5#
With MySQL v8+ you could use window functions
6qftjkof6#
From MySQL 5.7 documentation
MySQL 5.7.5 and up implements detection of functional dependence. If the ONLY_FULL_GROUP_BY SQL mode is enabled (which it is by default), MySQL rejects queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on them.
This means that @Jader Dias's solution wouldn't work everywhere.
Here is a solution that would work when
ONLY_FULL_GROUP_BY
is enabled:pjngdqdw7#
You should use some aggregate function to get the value of AnotherColumn that you want. That is, if you want the lowest value of AnotherColumn for each value of SomeColumn (either numerically or lexicographically), you can use:
Some hopefully helpful links:
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
http://www.oreillynet.com/databases/blog/2007/05/debunking_group_by_myths.html
h43kikqp8#
I have not seen the following solution among the answers, so I thought I'd put it out there.
The problem is to select rows which are the first rows when ordered by
AnotherColumn
in all groups grouped bySomeColumn
.The following solution will do this in MySQL.
id
has to be a unique column which must not hold values containing-
(which I use as a separator).There is a feature request for
FIRST()
andLAST()
in the MySQL bug tracker, but it was closed many years back.xyhw6mcr9#
I suggest to use this official way from MySql:
With this way, we can get the highest price on each article
yqyhoc1h10#
How about this:
643ylb0811#
Yet another way to do it (without the primary key) would be using the JSON functions:
or pre 5.7.22
Ordering (or filtering) can be done before grouping:
... or after grouping (of course):
Admittedly, it's rather convoluted and performance is probably not great (didn't test it on large data, works well on my limited data sets).
2q5ifsrm12#
Yet another way to do it
Select max from group that works in views
ca1c2owp13#
Select the first row for each group**(as ordered by a column)**in Mysql .
We have:
a table:mytable
a column we are ordering by:the_column_to_order_by
a column that we wish to group by:the_group_by_column
Here's my solution. The inner query gets you a unique set of rows, selected as a dual key. The outer query joins the same table by joining on both of those keys (with AND).
FYI: I haven't thought about efficiency at all for this and can't speak to that one way or the other.
ds97pgxw14#
I recently discovered a cool trick to accomplish this. Basically just make two different subqueries from a table and join them together. One of the subqueries does the aggregation based on a grouping, and the other subquery just grabs the first DISTINCT row for each grouped item.
When you join these subqueries together, you will get the first distinct item from each group, but will also get the aggregated columns across the whole group for each item. This is essentially the same result as having ONLY_FULL_GROUP_BY turned off.
ercv8c1e15#
rtribaldos mentioned that in younger database versions,window-functionscould be used.
Here is a code which worked for me and was as fast as Martin Zwarík'ssubstring_index-solution (in Mariadb 10.5.16):