Als ik dit goed ontcijfer, wil je in principe alle mensen selecteren waarvan het rijnummer volgens de aflopende ID in het adres verschijnt. Het uiteindelijke resultaat moet dan worden beperkt tot bepaalde van deze rijnummers.
Dan hoef je die omslachtige LIMIT
niet te gebruiken /OFFSET
helemaal niet bouwen. U kunt gewoon de row_number()
. gebruiken vensterfunctie.
Om te filteren op de rijnummers kunt u eenvoudig IN
. gebruiken . Afhankelijk van wat je hier wilt, kun je ofwel een lijst met letterlijke waarden gebruiken, vooral als de getallen niet opeenvolgend zijn. Of u kunt generate_series()
. gebruiken om een lijst met opeenvolgende nummers te genereren. Je kunt natuurlijk ook een subquery gebruiken, als de getallen in een andere tabel zijn opgeslagen.
Met een lijst van letterlijke woorden die er ongeveer zo uit zouden zien:
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);
Als u generate_series()
. wilt gebruiken een voorbeeld zou zijn:
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));
En een subquery van een andere tabel kan als volgt worden gebruikt:
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);
Voor grotere getallenreeksen kunt u ook overwegen om een INNER JOIN
. te gebruiken op de cijfers in plaats van IN
.
Met behulp van 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, '%');
Of als de getallen in een andere tabel staan:
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, '%');
Merk op dat ik ook de reguliere expressiepatroonovereenkomst heb gewijzigd in een eenvoudige LIKE
. Dat zou de query's een beetje draagbaarder maken. Maar je kunt dat natuurlijk vervangen door elke uitdrukking die je echt nodig hebt.
db<>fiddle (met enkele varianten)