sql server-唯一sql查询出现问题



我想选择所有记录,但查询每个产品名称只返回一条记录。我的表格看起来类似于:

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

最新更新