sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur kör man i psql en Loop för en Select-fråga med CTE:er och får utdata som visas om jag kör den i en skrivskyddad db?

Om jag dechiffrerar detta rätt vill man i princip välja alla personer där radnumret enligt det fallande ID:t står i adressen. Det slutliga resultatet bör då begränsas till vissa av dessa radnummer.

Då behöver du inte använda den där besvärliga LIMIT /OFFSET konstruera överhuvudtaget. Du kan helt enkelt använda row_number() fönsterfunktion.

För att filtrera efter radnumren kan du helt enkelt använda IN . Beroende på vad du vill ha här kan du antingen använda en lista med bokstaver, speciellt om siffrorna inte är konsekutiva. Eller så kan du använda generate_series() för att skapa en lista med på varandra följande nummer. Naturligtvis kan du också använda en underfråga, när siffrorna lagras i en annan tabell.

Med en lista över bokstavliga ord som skulle se ut ungefär så här:

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

Om du vill använda generate_series() ett exempel skulle vara:

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

Och en underfråga till en annan tabell kan användas så här:

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

För större uppsättningar nummer kan du också överväga att använda en INNER JOIN på siffrorna istället för IN .

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

Eller när siffrorna finns i en annan tabell:

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

Observera att jag också ändrade matchningen av det reguljära uttrycket till en enkel LIKE . Det skulle göra frågorna lite mer portabla. Men du kan naturligtvis ersätta det med vilket uttryck du verkligen behöver.

db<>fiol (med några av varianterna)




  1. Magento install klagar på att InnoDB saknas när den är tillgänglig

  2. Postgres-fel i batchinfogning:relation hibernate_sequence existerar inte position 17

  3. CHARTOROWID() Funktion i Oracle

  4. InnoDB prestandajusteringar