sql >> Database >  >> RDS >> PostgreSQL

Hoe voer ik in psql een lus uit voor een Select-query met CTE's en krijg ik de weergegeven uitvoer als ik deze in een alleen-lezen db uitvoer?

Als ik dit goed ontcijfer, wil je in principe alle mensen selecteren waarvan het rijnummer volgens de aflopende ID in het adres verschijnt. Het uiteindelijke resultaat moet dan worden beperkt tot bepaalde van deze rijnummers.

Dan hoef je die omslachtige LIMIT niet te gebruiken /OFFSET helemaal niet bouwen. U kunt gewoon de row_number() . gebruiken vensterfunctie.

Om te filteren op de rijnummers kunt u eenvoudig IN . gebruiken . Afhankelijk van wat je hier wilt, kun je ofwel een lijst met letterlijke waarden gebruiken, vooral als de getallen niet opeenvolgend zijn. Of u kunt generate_series() . gebruiken om een ​​lijst met opeenvolgende nummers te genereren. Je kunt natuurlijk ook een subquery gebruiken, als de getallen in een andere tabel zijn opgeslagen.

Met een lijst van letterlijke woorden die er ongeveer zo uit zouden zien:

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

Als u generate_series() . wilt gebruiken een voorbeeld zou zijn:

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

En een subquery van een andere tabel kan als volgt worden gebruikt:

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

Voor grotere getallenreeksen kunt u ook overwegen om een ​​INNER JOIN . te gebruiken op de cijfers in plaats van IN .

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

Of als de getallen in een andere tabel staan:

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

Merk op dat ik ook de reguliere expressiepatroonovereenkomst heb gewijzigd in een eenvoudige LIKE . Dat zou de query's een beetje draagbaarder maken. Maar je kunt dat natuurlijk vervangen door elke uitdrukking die je echt nodig hebt.

db<>fiddle (met enkele varianten)




  1. Onbekende kolom in 'veldlijst' wanneer de tijdelijke aanduiding van de voorbereide instructie zich in de subquery bevindt

  2. MySQL alleen binnen de huidige maand?

  3. Hoe u uw SQL-server kunt versnellen met behulp van Database Performance Monitoring

  4. Controleren of Oracle Client al dan niet is geïnstalleerd als voorwaarde voor installatie van componenten?