Наистина не съм сигурен в коя посока да отида с това ... Опитвам се да избера списък с клиенти въз основа на следните правила:
Изберете всички редове от клиент, където класиране = 1,
ИЛИ, ако класирането = 1 И въведете = съхранявайте тогава ранг 1 и върнете реда с ранг 2.
ИЛИ, ако клиентът има само един ред, върнете го дори ако тип = Store.
Класирането не се присвоява с ранг в заявката. По-скоро това е действителна колона в таблицата на клиентите (населена от съхранен процес, който прави класирането).
С помощта на примера по-долу ще се върне редове 1, 4, 6 и 10.
Клиентска таблица
RowID CustID Type Ranking
----- ------ ---- -------
1 9 Web 1
2 9 Catalog 2
3 9 Store 3
4 10 Store 1
5 11 Store 1
6 11 Web 2
7 12 Store 1
8 12 Web 2
9 12 Catalog 3
10 13 Web 1
Чувствам, че тази задача е по-трудна ЗАЩОТО Класирането вече е направено, когато таблицата е създадена! Всички предложения са добре дошли!
Отговори:
1 за отговор № 1Можеш да опиташ нещо подобно (не съм го тествал!):
SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE (c.Ranking = 1 AND c.Type != "Store")
OR (c.Type = "Store" AND Ranking = 2)
OR (c.Type = "Store" AND Ranking = 1 AND NOT EXISTS (SELECT 1 FROM Customer WHERE CustId = c.CustId AND Ranking = 2))
Ако таблицата на клиента е голяма, може да откриете, че заявката е малко бавна и нещо подобно ще бъде по-бързо:
SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE c.Ranking = 1 AND c.Type != "Store"
UNION ALL
SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE c.Type = "Store" AND Ranking = 2
UNION ALL
SELECT
RowId,
CustId,
Type,
Ranking
FROM Customer c
WHERE c.Type = "Store" AND Ranking = 1 AND NOT EXISTS (SELECT 1 FROM Customer WHERE CustId = c.CustId AND Ranking = 2)
0 за отговор № 2
Както и при другия отговор, не съм правил многозадълбочено тестване, но ето какво ще разгледам. Идеята тук е да се изгради номер на ред над типа на приоритизиране на набора от данни: да се съхранява в горната част и след това да се използва ранг като вторично състояние на сортиране.
select *
from (
select
rid = row_number() over (partition by CustID, order by case when type = "Store" then 0 else 1 end, Rank desc),
rowid,
CustID,
Type,
Ranking
from customer)
where RID = 1
0 за отговор № 3
Опитвам:
SELECT *
FROM Customer c
WHERE
-- There"s only one row for this customer
(
SELECT COUNT(*)
FROM Customer
WHERE CustID = c.CustID
) = 1
-- There"s a row with Ranking = 1 and Type = "Store", so select Ranking = 2
OR (Ranking = 2 AND EXISTS (SELECT 1 FROM Customer WHERE CustID = c.CustID AND Ranking = 1 AND Type = "Store"))
-- There"s a row with Ranking = 1 that"s not Type = "Store"
OR (Ranking = 1 AND Type <> "Store")