Группировка SQL по вопросу

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть таблица, которая отслеживает просмотры продуктов.

 TrackId ProductId CreatedOn
1       1         01/01/2011
2       4         01/01/2011
3       4         01/01/2011
4       10        01/01/2011
  

Что я хочу сделать, так это вернуть набор данных, в котором нет двух идентификаторов продукта рядом друг с другом. Т.е. из приведенного выше набора данных я хотел бы вернуть:

 TrackId ProductId CreatedOn
1       1         01/01/2011
2       4         01/01/2011
4       10        01/01/2011
  

Насколько мне известно, я не могу использовать distinct, поскольку это основано на строках?

Помощь приветствуется.

Комментарии:

1. Вы имеете в виду «отсутствие productid в двух смежных строках. Смежный определяется следующим / предыдущим Trackid»?

Ответ №1:

Сгенерируйте последовательность номеров строк для каждого идентификатора продукта, возьмите первый

 ;WITH cte AS
(
    SELECT
       *,
       ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY TrackID) AS rn
    FROM
       MyProductTable
)
SELECT
   TrackId ProductId CreatedOn
FROM
   cte
WHERE
   rn = 1
  

Редактировать:

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

Это основано на моем комментарии к вопросу

«отсутствует productid в двух смежных строках. Смежный определяется идентификатором следующего / предыдущего трека»

 SELECT
    M.*
FROM
    myProductTable M
    JOIN
    ( --gets the lowest TrackID for a ProductID
    SELECT ProductID, MIN(TrackID) AS MinTrackID
    FROM myProductTable
    GROUP BY ProductID
    ) M2 ON M.ProductID= M2.ProductID AND M.TrackID= M2.MinTrackID
  

Комментарии:

1. 1 @izip, если вы не использовали CTE и функции ранжирования SQL 2005 , то изучите их. Они будут хорошо служить вам.

Ответ №2:

 select min(TrackId), ProductId, CreatedOn
from YourTable
group by ProductId, CreatedOn;
  

Комментарии:

1. Что, если CreatedOn отличается для данного ProductID? Тогда у вас неверный вывод…

Ответ №3:

Вы можете сгруппировать по идентификаторам TrackID и ProductID и указать минимум созданного, если дата не важна.

 SELECT TrackID ,ProductID ,MIN(CreatedOn)
FROM [table]
GROUP BY TrackID ,ProductID
  

Если дата одинакова, вы можете сгруппировать по всем трем

 SELECT TrackID ,ProductID ,CreatedOn
FROM [table]
GROUP BY TrackID ,ProductID ,CreatedOn
  

Комментарии:

1. Мне нужно вернуть полный набор данных.

2. @izip: вы не можете вернуть «полный набор данных», если хотите удалить некоторые строки

3. Извините, я имел в виду все столбцы. Способ CTE сработал. Спасибо за ваше время