Si je déchiffre ce droit, vous voulez essentiellement sélectionner toutes les personnes où le numéro de ligne selon l'ID décroissant apparaît dans l'adresse. Le résultat final devrait alors être limité à certains de ces numéros de ligne.
Ensuite, vous n'avez pas besoin d'utiliser cette lourde LIMIT
/OFFSET
construire du tout. Vous pouvez simplement utiliser le row_number()
fonction fenêtre.
Pour filtrer les numéros de ligne, vous pouvez simplement utiliser IN
. Selon ce que vous voulez ici, vous pouvez soit utiliser une liste de littéraux, surtout si les nombres ne sont pas consécutifs. Ou vous pouvez utiliser generate_series()
pour générer une liste de numéros consécutifs. Bien sûr, vous pouvez également utiliser une sous-requête, lorsque les nombres sont stockés dans une autre table.
Avec une liste de littéraux qui ressemblerait à ceci :
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);
Si vous souhaitez utiliser generate_series()
un exemple serait :
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));
Et une sous-requête d'une autre table pourrait être utilisée comme ceci :
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);
Pour de plus grands ensembles de nombres, vous pouvez également envisager d'utiliser un INNER JOIN
sur les chiffres au lieu de IN
.
Utilisation de 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 lorsque les nombres sont dans une autre table :
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, '%');
Notez que j'ai également changé le modèle d'expression régulière correspondant à un simple LIKE
. Cela rendrait les requêtes un peu plus portables. Mais vous pouvez bien sûr remplacer cela par n'importe quelle expression dont vous avez vraiment besoin.
db<>violon (avec certaines variantes)