Я изо всех сил пытаюсь это проработать весь день - это кажется довольно простым, но мне чего-то не хватает!Фильтрация результатов, возвращаемых SQL-запросом
У меня есть запрос, который возвращает некоторые данные, два из возвращаемых им столбцов - это «PackageWeight» и «PackageGroup». По сути, я хочу отфильтровать эти данные, чтобы показать только одну строку для каждой «PackageGroup» - это должна быть строка с наибольшим значением в столбце «PackageWeight».
Кажется простым, но я просто не могу заставить его работать на SQL Server, используя комбинацию TOP 1 и GROUP BY. Я должен что-то упустить!
SELECT VendorID, PackageID, PackageWeight, PackageGroup
FROM (SELECT VendorID, COUNT(*) AS qty
FROM VendorServices
GROUP BY VendorID
) cs
JOIN (SELECT PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup, COUNT(*) AS qty
FROM PackageServices
JOIN lookupPackages ON PackageServices.PackageID = lookupPackages.PackageID
GROUP BY PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup
) ps ON cs.qty >= ps.qty
WHERE (SELECT COUNT(*)
FROM VendorServices cs2
JOIN PackageServices ps2 ON cs2.ServiceTypeID = ps2.ServiceID
WHERE cs2.VendorID = cs.VendorID
AND ps2.PackageID = ps.PackageID
) = ps.qty
Этот запрос возвращает мне полный набор данных, который мне нужно отфильтровать. Однако мои попытки до сих пор не удалось :(
Любая помощь очень ценится
EDIT - Благодаря вкладчикам ниже, до сих пор у меня есть следующий запрос:
with result_cte as
(
SELECT VendorID, PackageID, PackageWeight, PackageGroup,
RANK() over (partition by PackageGroup order by PackageWeight desc) as [rank]
FROM (SELECT VendorID, COUNT(*) AS qty
FROM VendorServices
GROUP BY VendorID
) cs
JOIN (SELECT PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup, COUNT(*) AS qty
FROM PackageServices
JOIN lookupPackages ON PackageServices.PackageID = lookupPackages.PackageID
GROUP BY PackageServices.PackageID, lookupPackages.PackageWeight, lookupPackages.PackageGroup
) ps ON cs.qty >= ps.qty
WHERE (SELECT COUNT(*)
FROM VendorServices cs2
JOIN PackageServices ps2 ON cs2.ServiceTypeID = ps2.ServiceID
WHERE cs2.VendorID = cs.VendorID
AND ps2.PackageID = ps.PackageID
) = ps.qty
)
select *
from result_cte
WHERE [rank] = 1
ORDER BY VendorID
До сих пор, так Я все еще взгляну на оператор APPLY, предложенный @gbn, поскольку это для меня новичок, и мне все еще нужно провести некоторое тестирование, чтобы убедиться, что этот запрос работает в 100% случаев. Однако исходные указания хороши!
Спасибо всем, кто внес свой вклад до сих пор.
EDIT 2 - К сожалению, после заполнения базы данных более подробными данными этот запрос не работал. Кажется, что пропустили некоторые записи.
Возможно, мне нужно объяснить немного больше о том, что здесь происходит. Данные, возвращаемые моим исходным запросом, перечисляют каждый клиент в системе, а также полученный пакетный идентификатор (рассчитанный по этому запросу), а также вес и группу, назначенные этому Пакету в справочной таблице.
Мне нужно отфильтровать исходную таблицу результатов, чтобы я получал не более одного пакета от каждой группы для каждого клиента (у каждого клиента может быть пакет из одной или нескольких групп, но у него может не быть пакета из каждой группы)
Буду считать вас более свежим, поскольку я думаю, что я могу быть в ситуации «Не вижу дерева для деревьев»!
Спасибо всем.
возможно дубликат [SQL Server - ВЫБРАТЬ TOP 5 строк для каждого FK] (http://stackoverflow.com/questions/1450603/sql-server-select-top-5-rows -for-each-fk) или http://stackoverflow.com/q/1164483/27535. И еще десятки: http://stackoverflow.com/questions/tagged/greatest-n-per-group – gbn
какую версию SQL Server вы используете? – Lamak
@Lamak - SQL Server 2008. – JimmE