#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 сработал. Спасибо за ваше время