在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不兼容。
答案 0 :(得分:69)
我的回答只针对你帖子的标题,因为我不知道C#并且不理解给定的查询。但是在MySQL中,我建议你尝试子选择。首先获取一组有趣列的主键,然后从这些行中选择数据:
SELECT somecolumn, anothercolumn
FROM sometable
WHERE id IN (
SELECT min(id)
FROM sometable
GROUP BY somecolumn
);
答案 1 :(得分:19)
写作时
SELECT AnotherColumn
FROM Table
GROUP BY SomeColumn
;
有效。 IIRC在其他RDBMS中这样的语句是不可能的,因为不属于分组键的列被引用而没有任何聚合。
这个“怪癖”与我想要的非常接近。所以我用它来得到我想要的结果:
SELECT * FROM
(
SELECT * FROM `table`
ORDER BY AnotherColumn
) t1
GROUP BY SomeColumn
;
答案 2 :(得分:13)
这是您可以尝试的另一种方式,不需要该ID字段。
select some_column, min(another_column)
from i_have_a_table
group by some_column
我仍然同意lfagundes你应该添加一些主键..
还要注意,通过这样做,你不能(轻松)获得其他值与生成的some_colum,another_column对相同的行!你需要lfagundes apprach和PK才能做到这一点!
答案 3 :(得分:6)
您应该使用一些聚合函数来获取所需的AnotherColumn值。也就是说,如果你想为SomeColumn的每个值(数字或词典)获得AnotherColumn的最低值,你可以使用:
SELECT SomeColumn, MIN(AnotherColumn)
FROM YourTable
GROUP BY SomeColumn
一些希望有用的链接:
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
答案 4 :(得分:4)
MySQL 5.7.5及更高版本实现了对功能依赖的检测。如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下是这样),MySQL拒绝查询,其中选择列表,HAVING条件或ORDER BY列表引用既未在GROUP BY子句中命名也未在功能上依赖于它们的非聚合列
这意味着@Jader Dias的解决方案无处不在。
这是一个在tmp = conv(randn(1,len+nbmax),ckbeta);
tmp = cumsum(tmp);
CA = wkeep(tmp,len,'c');
for j=0:nblev-1
CD = 2^(j/2)*4^(-s)*2^(-j*s)*randn(1,len);
len = 2*len-nbmax;
CA = idwt(CA,CD,fs1,gs1,len);
end
fBm = wkeep(CA,L,'c');
fBm = fBm-fBm(1);
启用时可以使用的解决方案:
ONLY_FULL_GROUP_BY
答案 5 :(得分:2)
最佳性能且易于使用:
SELECT id, code,
SUBSTRING_INDEX( GROUP_CONCAT(price ORDER BY id DESC), ',', 1) first_found_price
FROM stocks
GROUP BY code
ORDER BY id DESC
答案 6 :(得分:2)
我建议从MySql使用这种官方方式:
const parent = this.r2.createElement('div'); // container div to our stuff
this.jsonHTML.forEach((element) => {
const attributes = Object.keys(element.attributes);
const el = element.tagName && this.r2.createElement(element.tagName);
const text = this.r2.createText(element.text);
if (!el) { // when there's no tag to create we just create text directly into the div.
this.r2.appendChild(
parent,
text
);
} else { // otherwise we create it inside <a></a>
this.r2.appendChild(
el,
text
);
this.r2.appendChild(
parent,
el
);
}
if (attributes.length > 0) {
attributes.forEach((name) => {
if (el) {
this.r2.setAttribute(el, name, element.attributes[name]); // just the value attribute for now
if (name === 'value') {
this.r2.listen(el, 'click', () => {
this.goto(element.attributes[name]); // event binding with property "value" as parameter to navigate to
})
}
} else {
throw new Error('no html tag specified as element...');
}
})
}
})
this.r2.appendChild(this.container.nativeElement, parent); // div added to the DOM
通过这种方式,我们可以获得每篇文章的最高价格
答案 7 :(得分:1)
我在答案中没有看到以下解决方案,所以我想我会把它放在那里。
问题是在按AnotherColumn
分组的所有组中按SomeColumn
排序时,选择第一行的行。
以下解决方案将在MySQL中执行此操作。 id
必须是唯一的列,不得包含-
的值(我将其用作分隔符)。
select t1.*
from mytable t1
inner join (
select SUBSTRING_INDEX(
GROUP_CONCAT(t3.id ORDER BY t3.AnotherColumn DESC SEPARATOR '-'),
'-',
1
) as id
from mytable t3
group by t3.SomeColumn
) t2 on t2.id = t1.id
-- Where
SUBSTRING_INDEX(GROUP_CONCAT(id order by AnotherColumn desc separator '-'), '-', 1)
-- can be seen as:
FIRST(id order by AnotherColumn desc)
-- For completeness sake:
SUBSTRING_INDEX(GROUP_CONCAT(id order by AnotherColumn desc separator '-'), '-', -1)
-- would then be seen as:
LAST(id order by AnotherColumn desc)
MySQL错误跟踪器中有FIRST()
和LAST()
feature request,但它已在多年前关闭。
答案 8 :(得分:1)
另一种方法(不使用主键)将使用JSON函数:
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") )
from sometable group by somecolumn
或低于5.7.22
select somecolumn,
json_unquote(
json_extract(
concat('["', group_concat(othercolumn separator '","') ,'"]')
,"$[0]" )
)
from sometable group by somecolumn
排序(或过滤)可以在分组之前完成:
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") )
from (select * from sometable order by othercolumn) as t group by somecolumn
...或分组后(当然):
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") ) as other
from sometable group by somecolumn order by other
诚然,它相当复杂,性能可能也不是很好(没有在大数据上进行测试,在我有限的数据集上也能很好地工作)。
答案 9 :(得分:1)
SELECT
t1.*
FROM
table_name AS t1
LEFT JOIN table_name AS t2 ON (
t2.group_by_column = t1.group_by_column
-- group_by_column is the column you would use in the GROUP BY statement
AND
t2.order_by_column < t1.order_by_column
-- order_by_column is column you would use in the ORDER BY statement
-- usually is the autoincremented key column
)
WHERE
t2.group_by_column IS NULL;
在MySQL v8 +中,您可以使用窗口功能
答案 10 :(得分:0)
另一种方法
从在视图中工作的组中选择最大值
SELECT * FROM action a
WHERE NOT EXISTS (
SELECT 1 FROM action a2
WHERE a2.user_id = a.user_id
AND a2.action_date > a.action_date
AND a2.action_type = a.action_type
)
AND a.action_type = "CF"
答案 11 :(得分:0)
这个怎么样:
SELECT SUBSTRING_INDEX(
MIN(CONCAT(OrderColumn, '|', IFNULL(TargetColumn, ''))
), '|', -1) as TargetColumn
FROM table
GROUP BY GroupColumn
答案 12 :(得分:0)
在Mysql中为每个组(按列排序)选择第一行。
我们有:
表格: mytable
我们按以下顺序排序的列: the_column_to_order_by
我们希望分组的列: the_group_by_column
这是我的解决方案。 内部查询为您提供一组唯一的行,这些行被选择为双键。 外部查询通过对两个键(使用AND)进行联接来联接同一表。
SELECT * FROM
(
SELECT the_group_by_column, MAX(the_column_to_order_by) the_column_to_order_by
FROM mytable
GROUP BY the_group_by_column
ORDER BY MAX(the_column_to_order_by) DESC
) as mytable1
JOIN mytable mytable2 ON mytable2.the_group_by_column =
mytablealiamytable2.the_group_by_column
AND mytable2.the_column_to_order_by = mytable1.the_column_to_order_by;
仅供参考:我根本没有考虑过效率,也不能以一种或另一种方式谈论。
答案 13 :(得分:0)
我最近发现了一个很酷的技巧来实现这一点。基本上只是从一个表中创建两个不同的子查询并将它们连接在一起。其中一个子查询根据分组进行聚合,另一个子查询仅获取每个分组项的第一个 DISTINCT 行。
当您将这些子查询连接在一起时,您将从每个组中获得第一个不同的项目,但也会为每个项目获得整个组中的聚合列。这与关闭 ONLY_FULL_GROUP_BY 的结果基本相同。
userId
答案 14 :(得分:-3)
为什么不使用MySQL LIMIT关键字?
SELECT [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]
LIMIT 1