Проблема с уникальным запросом SQL - PullRequest
0 голосов
/ 30 апреля 2011

Я хочу выбрать все записи, но запрос должен возвращать только одну запись на имя продукта.Моя таблица выглядит примерно так:

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.Мой стол не такой простой, как этот, это всего лишь образец.Каково решение?Это понятно?

Ответы [ 4 ]

2 голосов
/ 30 апреля 2011
Select  ProductName, 
min(Comment) , min(SellId) from TBL#Sells
group by ProductName

Если вам нужна только одна запись для каждого названия продукта, вы, конечно, должны выбрать, какое значение вы хотите для других полей.

Если вы агрегируете (используя group by), вы можете выбрать aggregate function, функцию, которая принимает список значений и возвращает только одно: здесь я выбрал MIN: это наименьшее значение длякаждое поле.

ПРИМЕЧАНИЕ: комментарии и sellid могут поступать из разных записей, так как MIN берется ...

Другие агрегаты, которые могут оказаться полезными:

FIRST : first record encountered
LAST : last record encoutered
AVG : average 
COUNT : number of records

первый / последнийпреимущество в том, что все поля принадлежат одной записи.

2 голосов
/ 30 апреля 2011
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 - это автоматически увеличивающаяся идентификационная величина, которая увеличивается.

0 голосов
/ 01 мая 2011
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
0 голосов
/ 30 апреля 2011

Я знаю, у вас уже есть ответ, я хотел бы предложить способ, который был бы наиболее быстрым с точки зрения производительности для меня, в аналогичной ситуации. Я предполагаю, что 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 в длинном столбце char):

select 
    * 
from
(
    select 
        *,ROW_NUMBER() over (PARTITION BY ProductName order by SellId) OccurenceId 
    from sells
) x
where 
    OccurenceId = 1

Преимущество этого в том, что его гораздо легче читать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...