sql >> Databáze >  >> RDS >> PostgreSQL

Jak v psql spustit smyčku pro výběrový dotaz s CTE a zobrazit výstup, pokud jej spustím v db pouze pro čtení?

Pokud toto právo dešifruji, v podstatě chcete vybrat všechny osoby, kde se v adrese objevuje číslo řádku podle sestupného ID. Konečný výsledek by pak měl být omezen na některá z těchto čísel řádků.

Pak nemusíte používat tento těžkopádný LIMIT /OFFSET vůbec konstruovat. Můžete jednoduše použít row_number() funkce okna.

Chcete-li filtrovat čísla řádků, můžete jednoduše použít IN . V závislosti na tom, co zde chcete, můžete buď použít seznam literálů, zvláště pokud čísla nejsou po sobě jdoucí. Nebo můžete použít generate_series() pro vygenerování seznamu po sobě jdoucích čísel. Samozřejmě můžete použít i poddotaz, kdy jsou čísla uložena v jiné tabulce.

Se seznamem literálů, které by vypadaly asi takto:

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);

Pokud chcete použít generate_series() příklad by byl:

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));
                             

A poddotaz jiné tabulky lze použít takto:

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);

Pro větší sady čísel můžete také zvážit použití INNER JOIN na čísla místo IN .

Pomocí 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, '%');

Nebo když jsou čísla v jiné tabulce:

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, '%');

Všimněte si, že jsem také změnil shodu se vzorem regulárního výrazu na jednoduchý LIKE . Díky tomu by byly dotazy o něco přenosnější. Ale můžete to samozřejmě nahradit jakýmkoli výrazem, který opravdu potřebujete.

db<>fiddle (s některými variantami)




  1. Jak vytisknout tabulku databáze MySQL v PHP pomocí PDO

  2. Najděte překrývající se období v PostgreSQL

  3. Přidejte 1 do pole

  4. Uživatelská databáze MySQL nemá sloupce s hesly - Instalace MySQL na OSX