/ / Как да изберете или прескочите към следващия ред, ако отговаря на определени критерии - sql, sql-server, tsql, ranking

Как да изберете или прескочите до следващия ред, ако отговаря на определени критерии - sql, sql-server, tsql, класиране

Наистина не съм сигурен в коя посока да отида с това ... Опитвам се да избера списък с клиенти въз основа на следните правила:

  • Изберете всички редове от клиент, където класиране = 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")