Om jag dechiffrerar detta rätt vill man i princip välja alla personer där radnumret enligt det fallande ID:t står i adressen. Det slutliga resultatet bör då begränsas till vissa av dessa radnummer.
Då behöver du inte använda den där besvärliga LIMIT
/OFFSET
konstruera överhuvudtaget. Du kan helt enkelt använda row_number()
fönsterfunktion.
För att filtrera efter radnumren kan du helt enkelt använda IN
. Beroende på vad du vill ha här kan du antingen använda en lista med bokstaver, speciellt om siffrorna inte är konsekutiva. Eller så kan du använda generate_series()
för att skapa en lista med på varandra följande nummer. Naturligtvis kan du också använda en underfråga, när siffrorna lagras i en annan tabell.
Med en lista över bokstavliga ord som skulle se ut ungefär så här:
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);
Om du vill använda generate_series()
ett exempel skulle vara:
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));
Och en underfråga till en annan tabell kan användas så här:
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);
För större uppsättningar nummer kan du också överväga att använda en INNER JOIN
på siffrorna istället för IN
.
Använder 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 siffrorna finns i en annan tabell:
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, '%');
Observera att jag också ändrade matchningen av det reguljära uttrycket till en enkel LIKE
. Det skulle göra frågorna lite mer portabla. Men du kan naturligtvis ersätta det med vilket uttryck du verkligen behöver.
db<>fiol (med några av varianterna)