Jeśli dobrze to rozszyfruję, w zasadzie chcesz wybrać wszystkie osoby, w których w adresie pojawia się numer wiersza według malejącego identyfikatora. Ostateczny wynik powinien być wtedy ograniczony do niektórych z tych numerów wierszy.
Wtedy nie musisz używać tego uciążliwego LIMIT
/OFFSET
w ogóle konstruować. Możesz po prostu użyć row_number()
funkcja okna.
Aby filtrować według numerów wierszy, możesz po prostu użyć IN
. W zależności od tego, co chcesz tutaj, możesz użyć listy literałów, zwłaszcza jeśli liczby nie są kolejne. Możesz też użyć generate_series()
aby wygenerować listę kolejnych numerów. Oczywiście możesz również użyć podzapytania, gdy liczby są przechowywane w innej tabeli.
Z listą literałów, która wyglądałaby mniej więcej tak:
SELECT pn.personid,
pn.lastname,
pn.firstname,
pn.address,
pn.city
FROM (SELECT p.personid,
p.lastname,
p.firstname,
p.address,
p.city,
row_number() OVER (ORDER BY p.personid DESC) n
FROM persons p) pn
WHERE pn.address LIKE concat('%', pn.n, '%')
AND pn.n IN (1, 2, 4);
Jeśli chcesz użyć generate_series()
przykładem może być:
SELECT pn.personid,
pn.lastname,
pn.firstname,
pn.address,
pn.city
FROM (SELECT p.personid,
p.lastname,
p.firstname,
p.address,
p.city,
row_number() OVER (ORDER BY p.personid DESC) n
FROM persons p) pn
WHERE pn.address LIKE concat('%', pn.n, '%')
AND pn.n IN (SELECT s.n
FROM generate_series(1, 3) s (n));
Podzapytanie z innej tabeli może być użyte w następujący sposób:
SELECT pn.personid,
pn.lastname,
pn.firstname,
pn.address,
pn.city
FROM (SELECT p.personid,
p.lastname,
p.firstname,
p.address,
p.city,
row_number() OVER (ORDER BY p.personid DESC) n
FROM persons p) pn
WHERE pn.address LIKE concat('%', pn.n, '%')
AND pn.n IN (SELECT t.nmuloc
FROM elbat t);
W przypadku większych zestawów liczb można również rozważyć użycie INNER JOIN
na liczbach zamiast IN
.
Używanie generate_series()
:
SELECT pn.personid,
pn.lastname,
pn.firstname,
pn.address,
pn.city
FROM (SELECT p.personid,
p.lastname,
p.firstname,
p.address,
p.city,
row_number() OVER (ORDER BY p.personid DESC) n
FROM persons p) pn
INNER JOIN generate_series(1, 1000000) s (n)
ON s.n = pn.n
WHERE pn.address LIKE concat('%', pn.n, '%');
Lub gdy liczby znajdują się w innej tabeli:
SELECT pn.personid,
pn.lastname,
pn.firstname,
pn.address,
pn.city
FROM (SELECT p.personid,
p.lastname,
p.firstname,
p.address,
p.city,
row_number() OVER (ORDER BY p.personid DESC) n
FROM persons p) pn
INNER JOIN elbat t
ON t.nmuloc = pn.n
WHERE pn.address LIKE concat('%', pn.n, '%');
Zauważ, że zmieniłem również dopasowanie wzorca wyrażenia regularnego do prostego LIKE
. Dzięki temu zapytania byłyby bardziej przenośne. Ale możesz to oczywiście zastąpić dowolnym wyrażeniem, którego naprawdę potrzebujesz.
db<>skrzypce (z niektórymi wariantami)