我想选择所有记录,但查询每个产品名称只返回一条记录。我的表格看起来类似于:
SellId ProductName Comment
1 Cake dasd
2 Cake dasdasd
3 Bread dasdasdd
其中产品名称不是唯一的。我希望查询为每个ProductName返回一条记录,结果如下:
SellId ProductName Comment
1 Cake dasd
3 Bread dasdasdd
我已经尝试过这个查询,
Select distict ProductName,Comment ,SellId from TBL#Sells
但它正在返回具有相同ProductName的多个记录。我的表并没有这么简单,这只是一个样本。解决方案是什么?清楚了吗?
Select ProductName,
min(Comment) , min(SellId) from TBL#Sells
group by ProductName
如果每个产品名称只需要一条记录,那么您当然必须选择其他字段的值。
如果聚合(使用分组依据(,则可以选择CCD_,htat是一个函数,它接受一个值列表,只返回一个:这里我选择了MIN
:这是每个字段的最小值。
注意:注释和sellid可以来自不同的记录,因为MIN是取的。。。
你可能会发现有用的其他聚合:
FIRST : first record encountered
LAST : last record encoutered
AVG : average
COUNT : number of records
first/last的优点是所有字段都来自同一记录。
SELECT S.ProductName, S.Comment, S.SellId
FROM
Sells S
JOIN (SELECT MAX(SellId)
FROM Sells
GROUP BY ProductName) AS TopSell ON TopSell.SellId = S.SellId
这将获得最新的注释作为您选择的注释,假设SellId是一个自动递增的标识。
我知道,你已经得到了答案,我想在类似的情况下为我提供一种性能最快的方法。我假设SellId是主键和身份。您希望在ProductName上建立索引以获得最佳性能。
select
Sells.*
from
(
select
distinct ProductName
from
Sells
) x
join
Sells
on
Sells.ProductName = x.ProductName
and Sells.SellId =
(
select
top 1 s2.SellId
from
Sells s2
where
x.ProductName = s2.ProductName
Order By SellId
)
一种较慢的方法(但仍然比长字符列上的GroupBy和MIN更好(是:
select
*
from
(
select
*,ROW_NUMBER() over (PARTITION BY ProductName order by SellId) OccurenceId
from sells
) x
where
OccurenceId = 1
这本书的一个优点是它更容易阅读。
create table Sale
(
SaleId int not null
constraint PK_Sale primary key,
ProductName varchar(100) not null,
Comment varchar(100) not null
)
insert Sale
values
(1, 'Cake', 'dasd'),
(2, 'Cake', 'dasdasd'),
(3, 'Bread', 'dasdasdd')
-- Option #1 with over()
select *
from Sale
where SaleId in
(
select SaleId
from
(
select SaleId, row_number() over(partition by ProductName order by SaleId) RowNumber
from Sale
) tt
where RowNumber = 1
)
order by SaleId
-- Option #2
select *
from Sale
where SaleId in
(
select min(SaleId)
from Sale
group by ProductName
)
order by SaleId
drop table Sale