Ако дешифрирам това правилно, всъщност искате да изберете всички хора, при които номерът на реда според низходящия ID се появява в адреса. Тогава крайният резултат трябва да бъде ограничен до някои от тези номера на редове.
Тогава не е необходимо да използвате този тромав LIMIT
/OFFSET
конструира изобщо. Можете просто да използвате row_number()
функция прозорец.
За да филтрирате номерата на редовете, можете просто да използвате IN
. В зависимост от това, което искате тук, можете да използвате или списък с литерали, особено ако числата не са последователни. Или можете да използвате 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
WHERE pn.address LIKE concat('%', pn.n, '%')
AND pn.n IN (1, 2, 4);
Ако искате да използвате 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
WHERE pn.address LIKE concat('%', pn.n, '%')
AND pn.n IN (SELECT s.n
FROM generate_series(1, 3) s (n));
И подзаявка на друга таблица може да се използва така:
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);
За по-големи набори от числа можете също да обмислите използването на INNER JOIN
върху числата вместо IN
.
Използване на 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, '%');
Или когато числата са в друга таблица:
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, '%');
Обърнете внимание, че също промених шаблона на регулярния израз, съответстващ на прост LIKE
. Това би направило заявките малко по-преносими. Но можете, разбира се, да го замените с всеки израз, от който наистина се нуждаете.
db<>fiddle (с някои от вариантите)