Sql server 唯一SQL查询存在问题
我想选择所有记录,但让查询只返回每个产品名称的单个记录。我的桌子看起来像:Sql server 唯一SQL查询存在问题,sql-server,sql-server-2005,Sql Server,Sql Server 2005,我想选择所有记录,但让查询只返回每个产品名称的单个记录。我的桌子看起来像: SellId ProductName Comment 1 Cake dasd 2 Cake dasdasd 3 Bread dasdasdd 其中产品名称不是唯一的。我希望查询返回每个ProductName的一条记录,结果如下: SellId ProductName Comment 1 Cake
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
但它将返回多个具有相同产品名称的记录。我的表格并没有这么简单,这只是一个样本。解决办法是什么?清楚吗
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是一个自动递增的标识,它将获取最新的注释作为您选择的注释
Select ProductName,
min(Comment) , min(SellId) from TBL#Sells
group by ProductName
假设SellId是一个自动递增的标识,它将获取最新的注释作为您选择的注释
Select ProductName,
min(Comment) , min(SellId) from TBL#Sells
group by ProductName
如果每个productname只需要一条记录,那么您当然必须为其他字段选择所需的值
如果聚合(使用分组依据),则可以选择一个聚合函数
,
htat是一个函数,它接受一个值列表,只返回一个值:这里我选择了MIN
:这是每个字段的最小值
注意:注释和sellid可以来自不同的记录,因为MIN是
此外,您可能会发现以下有用信息:
FIRST : first record encountered
LAST : last record encoutered
AVG : average
COUNT : number of records
first/last的优点是所有字段都来自同一条记录
如果每个productname只需要一条记录,那么您当然必须为其他字段选择所需的值
如果聚合(使用分组依据),则可以选择一个聚合函数
,
htat是一个函数,它接受一个值列表,只返回一个值:这里我选择了MIN
:这是每个字段的最小值
注意:注释和sellid可以来自不同的记录,因为MIN是
此外,您可能会发现以下有用信息:
FIRST : first record encountered
LAST : last record encoutered
AVG : average
COUNT : number of records
first/last的优点是所有字段都来自同一个记录。我知道,您已经得到了答案,我想提供一种在类似情况下对我来说性能最快的方法。我假设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
)
一种较慢的方法(但在长字符列上仍优于Group By和MIN)是:
这本书的一个优点是它更容易阅读。我知道,你已经有了答案,在类似的情况下,我想为我提供一种性能最快的方法。我假设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
)
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
一种较慢的方法(但在长字符列上仍优于Group By和MIN)是:
此代码的一个优点是易于阅读。您的代码的目标是什么?您想做什么?如果为cake提供多个注释,您希望在为cake返回的单行的注释列中看到什么?我希望选择所有记录,但任何产品名称都不应在查询中重复代码的目标是什么?你想做什么?给cake一个以上的注释,你想在为cake返回的单行的注释栏中看到什么?我想选择所有记录,但任何产品名称都不应该在queryI中重复。我认为他想要的是“min”。@leppie,确实,相应地修改了它,txThanks,我得到了我的答案。“Muchas Gracias”对于这个答案,我唯一要注意的是,注释不一定与SELLID匹配。因为您说过您的表更复杂,所以如果您希望值来自匹配的行,我只会注意一下。MIN注释实际上可能来自SellId的另一行。我认为,通过peter编写的查询,productname将是唯一的,并且不会在输出结果中重复?我认为他更希望使用“MIN”。@leppie确实相应地更改了它,txThanks,我得到了我的答案。“Muchas Gracias”对于这个答案,我唯一要注意的是,注释不一定与SELLID匹配。因为您说过您的表更复杂,所以如果您希望值来自匹配的行,我只会注意一下。MIN注释实际上可能来自SellId的另一行。我认为,在peter编写的查询中,productname将是唯一的,并且不会在输出结果中重复?谢谢,我得到了我的答案。“Muchas Gracias”我们不应该在join中包含产品名称吗?不,因为我在子查询中每个名称都有一个id。子查询按产品名称获取最新条目,第1部分获取其余详细信息。谢谢,我得到了我的答案。“Muchas Gracias”我们不应该在加入中包含产品名称吗?不,因为我在子查询中每个名称已经有1个id。子查询按产品名称获取最新条目,第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