/ / Jak wybrać lub przejść do następnego wiersza, jeśli spełnia określone kryteria - sql, sql-server, tsql, ranking

Jak wybrać lub przejść do następnego wiersza, jeśli spełnia określone kryteria - sql, sql-server, tsql, ranking

Naprawdę nie jestem nawet pewien, w którą stronę pójść ... Próbuję wybrać listę klientów na podstawie następujących zasad:

  • Wybierz wszystkie wiersze od Klienta, gdzie Ranking = 1,

  • LUB jeśli Ranking = 1 ORAZ Typ = Przechowuj następnie w Rank 1 i zwróć wiersz z Rank 2.

  • LUB jeśli klient ma tylko 1 wiersz, zwróć go, nawet jeśli typ = Sklep.

Rankingowi nie przypisano instrukcji Rank w zapytaniu. Jest to raczej rzeczywista kolumna w tabeli Klientów (wypełniona przechowywanym procem, który zajmuje pozycję w rankingu).

Korzystając z poniższego przykładu, chciałbym zwrócić wiersze 1, 4, 6 i 10.

Tabela klientów

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

Wydaje mi się, że to zadanie jest trudniejsze PONIEWAŻ Ranking jest już gotowy, gdy tworzony jest stół! Wszelkie sugestie są mile widziane!

Odpowiedzi:

1 dla odpowiedzi № 1

Możesz spróbować czegoś takiego (nie przetestowałem tego!):

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))

Jeśli tabela klientów jest duża, może się okazać, że zapytanie jest nieco wolne i coś takiego byłoby szybsze:

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 dla odpowiedzi nr 2

Podobnie jak w przypadku innej odpowiedzi, nie zrobiłem wieledokładne testy, ale oto, na co bym spojrzał. Chodzi o to, aby zbudować numer_wiersza nad zestawem danych, nadając priorytet typowi: zapisz na górę, a następnie używając rangi jako warunku sortowania wtórnego.

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 dla odpowiedzi № 3

Próbować:

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")