Se eu decifrar isso direito, você basicamente quer selecionar todas as pessoas onde o número da linha de acordo com o ID descendente aparece no endereço. O resultado final deve ser limitado a alguns desses números de linha.
Então você não precisa usar esse incômodo
LIMIT
/OFFSET
construir em tudo. Você pode simplesmente usar o row_number()
função de janela. Para filtrar os números das linhas, você pode simplesmente usar
IN
. Dependendo do que você quer aqui, você pode usar uma lista de literais, especialmente se os números não forem consecutivos. Ou você pode usar generate_series()
para gerar uma lista de números consecutivos. Claro que você também pode usar uma subconsulta, quando os números são armazenados em outra tabela. Com uma lista de literais que seria algo assim:
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);
Se você quiser usar
generate_series()
um exemplo seria: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));
E uma subconsulta de outra tabela poderia ser usada assim:
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);
Para conjuntos maiores de números, você também pode usar um
INNER JOIN
nos números em vez de IN
. Usando
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, '%');
Ou quando os números estão em outra tabela:
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, '%');
Observe que também alterei a correspondência de padrão de expressão regular para um simples
LIKE
. Isso tornaria as consultas um pouco mais portáteis. Mas é claro que você pode substituir isso por qualquer expressão que realmente precise. db<>fiddle (com algumas das variantes)