Mam takie 2 tabele:
CREATE TABLE account (
id INT
);
CREATE TABLE device (
id INT,
account_id INT,
token text
);
W ten sposób mogę wyświetlić konta wraz z ich wszystkimi urządzeniami:
select *
from account a
inner join device d on a.id = d.account_id
https://www.db-fiddle.com/f/vZCNfgvppXhmnz8sHbaWda/15
Nie ma też problemu, by wprowadzić paginację:
select *
from
(
select *
from account a
order by a.id
offset 0 rows
fetch first 3 rows only
) a
inner join device d on d.account_id = a.id
https://www.db-fiddle.com/f/vZCNfgvppXhmnz8sHbaWda/14
Mogę też dodać filtrowanie - wyświetlać konta (wraz z ich wszystkimi urządzeniami), ale tylko wtedy, gdy zawierają urządzenie z tokenem 'BIZ':
select *
from
(
select *
from account a
where exists (select 1 from device d where d.account_id = a.id and d.token like 'BIZ%')
order by a.id
offset 0 rows
fetch first 3 rows only
) a
inner join device d on d.account_id = a.id
https://www.db-fiddle.com/f/vZCNfgvppXhmnz8sHbaWda/13
Teraz chciałbym dodać coś szalonego - do powyższego zapytania dodać sortowanie po tokenie. Dla paginacji:
offset 0 rows
fetch first 3 rows only
i sortowaniu rosnąco powinienem otrzymać:
| account_id | token |
|------------|---------|
| 1 | BIZ-111 |
| 1 | BIZ-333 |
| 1 | ONZ-555 |
| 4 | BIZ-222 |
| 8 | BIZ-444 |
a przy sortowaniu malejąco:
| account_id | token |
|------------|---------|
| 3 | BIZ-999 |
| 7 | BIZ-888 |
| 2 | BIZ-777 |
| 2 | BIZ-666 |
Niestety polegam na tym tworząc coraz to większe spahetti. Aktualnie mam coś takiego:
Dla sortowania rosnąco:
with cte as
(
select
a.id
from account a
inner join device d on d.account_id = a.id
where d.token like 'BIZ%'
group by a.id
order by max(d.token) asc
offset 0 rows
fetch first 3 rows only
)
select
cte.id,
d.token
from cte
inner join device d on d.account_id = cte.id
order by d.token asc
https://www.db-fiddle.com/f/vZCNfgvppXhmnz8sHbaWda/17
I malejąco:
with cte as
(
select
a.id
from account a
inner join device d on d.account_id = a.id
where d.token like 'BIZ%'
group by a.id
order by max(d.token) desc -- tutaj zamiana z 'asc' na 'desc'
offset 0 rows
fetch first 3 rows only
)
select
cte.id,
d.token
from cte
inner join device d on d.account_id = cte.id
order by d.token desc -- tutaj zamiana z 'asc' na 'desc'
https://www.db-fiddle.com/f/vZCNfgvppXhmnz8sHbaWda/16
Co prawda kolejność kont nie jest dokładnie tak jak chciałem, ale ja i tak potem muszę grupować wynik zapytania, a kolejność względem kont, jak i tokenów względem jednego konta jest już zachowana.
Macie propozycje, czy da się to zrobić zwięźlej? Generalnie problem polega na tym, że chciałbym dodać sortowanie po innych rzeczach niż token i robi się straszne spaghetti.. Mam to rozwiązane (chyba niestety) w taki sposób, że w zależności co zaznaczy użytkownik (filtrowanie, sortowanie), to edytuję ten kod sql.. Nie chcecie tego wiedzieć..