选择行,其中一列的值最小。

huangapple go评论69阅读模式
英文:

Selecting rows, where a column is at its minimal value

问题

在上述列表中,例如,Group 200 仅应返回一行 - 第四行 - 因为第二行也属于组 100,因此不应列在 200 下...

英文:

The otherwise identical rows here can sometimes differ by a numerical value of one column, let's call it Group:

Col1 Col2 ..... Group
A B 100
A B 200
A C 100
A D 200

For a particular value of group, how do I select only the rows, for which it is the minimal one?

In the above listing, for example, group 200 shall only return one row -- the fourth one -- because the second row is also a member of group 100, and thus shall not be listed under the 200...

答案1

得分: 1

尝试示例

创建表test(Col1 varchar(1),Col2 varchar(1),GroupN int);
将数据插入test表
('A','B',100),
('A','B',200),
('A','C',100),
('A','D',200);

使用minGroup作为(
选择Col1,Col2,min(GroupN)作为GroupN
从test表中
按Col1,Col2分组)
选择a.Col1,a.Col2,a.GroupN
从test表a
内部连接minGroup表b
在a.Col1 = b.Col1和a.Col2 = b.Col2时
其中b.GroupN = 200

对于GroupN = 200的结果为

Col1 Col2 GroupN
A D 200

对于GroupN = 100的结果为

Col1 Col2 GroupN
A B 100
A B 200
A C 100

然而,更清晰的选项在SQL Server 2008中有效

选择*
从(
选择Col1,Col2,GroupN
,min(GroupN)over(按Col1,Col2分区)作为minGroupN
从test表
)minGroup
其中minGroupN = 100的结果为


<details>
<summary>英文:</summary>

Try example

create table test(Col1 varchar(1),Col2 varchar(1),GroupN int);
insert into test values
('A','B',100)
,('A','B',200)
,('A','C',100)
,('A','D',200)
;
with minGroup as(
select Col1,Col2,min(GroupN) as GroupN
from test
group by Col1,Col2
)
select a.Col1,a.Col2,a.GroupN
from test a
inner join minGroup b on a.Col1=b.Col1 and a.Col2=b.Col2
where b.GroupN=200

For GroupN=200 result is  

|Col1|	Col2|	GroupN|
|:--|:--|---:|
|A	|D	|200|

For GroupN=100 result is

|Col1|	Col2|	GroupN|
|:--|:--|---:|
|A|	B|	100|
|A|	B|	200|
|A|	C|	100|

A clearer option, however, works in SQL Server 2008

select *
from (
select Col1,Col2,GroupN
,min(GroupN)over(partition by Col1,Col2) as minGroupN
from test
) minGroup
where minGroupN=100

In query plan weight of ``table scan``=22%, ``sort``=77%, all other=1%.
Nested queries in this case do not add complexity and do not cause performance loss. If you have index on (Col1,Col2 ...) query performance is adequately. 
[![Query plan][1]][1]


  [1]: https://i.stack.imgur.com/Mm0Fs.png

</details>



# 答案2
**得分**: 0

可以使用`LEFT JOIN`来实现:

```sql
select t.*
from mytable t
left join (
  select Col1, Col2
  from mytable
  where Group_ <> 200
) as s on t.Col1 = s.Col1 and t.Col2 = s.Col2
where Group_ = 200 and s.Col1 is null

结果:

Col1    Col2    Group_
A       D       200

演示链接

英文:

You can do it using LEFT JOIN as follows :

select t.*
from mytable t
left join (
  select Col1, Col2
  from mytable
  where Group_ &lt;&gt; 200
) as s on t.Col1 = s.Col1 and t.Col2 = s.Col2
where Group_ = 200 and s.Col1 is null

Result :

Col1	Col2	Group_
A	    D	    200

Demo here

huangapple
  • 本文由 发表于 2023年5月17日 06:26:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76267446.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定