Hvis jeg tyder dette rigtigt, vil du som udgangspunkt vælge alle personer, hvor rækkenummeret ifølge det faldende ID fremgår af adressen. Det endelige resultat bør så begrænses til visse af disse rækkenumre.
Så behøver du ikke bruge den besværlige LIMIT
/OFFSET
overhovedet konstruere. Du kan blot bruge row_number()
vinduesfunktion.
For at filtrere efter rækkenumrene kan du blot bruge IN
. Afhængigt af hvad du ønsker her, kan du enten bruge en liste over bogstaver, især hvis tallene ikke er fortløbende. Eller du kan bruge generate_series()
for at generere en liste over fortløbende numre. Du kan selvfølgelig også bruge en underforespørgsel, når tallene er gemt i en anden tabel.
Med en liste over bogstaver, der ville se sådan ud:
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);
Hvis du vil bruge generate_series()
et eksempel ville være:
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));
Og en underforespørgsel til en anden tabel kunne bruges sådan:
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);
For større sæt tal kan du også overveje at bruge en INNER JOIN
på tallene i stedet for IN
.
Brug af 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, '%');
Eller når tallene er i en anden tabel:
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, '%');
Bemærk, at jeg også ændrede det regulære udtryks mønstertilpasning til en simpel LIKE
. Det ville gøre forespørgslerne lidt mere bærbare. Men du kan selvfølgelig erstatte det med ethvert udtryk, du virkelig har brug for.
db<>fiddle (med nogle af varianterne)