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 № 1Moż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")