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

Postgres Error:Více než jeden řádek vrácený poddotazem použitým jako výraz

Technicky , pro opravu výpisu můžete přidat LIMIT 1 do poddotazu, abyste zajistili, že bude vrácen maximálně 1 řádek. Tím by se chyba odstranila, váš kód by byl stále nesmysl.

... 'SELECT store_key FROM store LIMIT 1' ...

Prakticky , chcete řádky nějak přiřadit místo vybírání libovolného řádku ze vzdálené tabulky store aktualizovat každý řádek vaší lokální tabulky customer .
Vaše základní otázka neposkytuje dostatek podrobností, takže předpokládám textový sloupec match_name v obou tabulkách (a UNIQUE v store ) pro tento příklad:

... 'SELECT store_key FROM store
     WHERE match_name = ' || quote_literal(customer.match_name)  ...

Ale to je extrémně drahý způsob, jak věci dělat.

V ideálním případě , úplně přepíšete prohlášení.

UPDATE customer c
SET    customer_id = s.store_key
FROM   dblink('port=5432, dbname=SERVER1 user=postgres password=309245'
            , 'SELECT match_name, store_key FROM store')
       AS s(match_name text, store_key integer)
WHERE c.match_name = s.match_name
AND   c.customer_id IS DISTINCT FROM s.store_key;

To řeší řadu problémů ve vašem původním prohlášení.

Je zřejmé, že základní problém vedoucí k vaší chybě je opraveno.

Obvykle je lepší připojit se k dalším vztahům v FROM klauzule UPDATE než spustit korelované dílčí dotazy pro každý jednotlivý řádek.

Při použití dblink se výše uvedené stává tisíckrát důležitější. Nechcete volat dblink() pro každý jednotlivý řádek je to extrémně drahé . Zavolejte jednou, abyste získali všechny potřebné řádky.

S korelovanými poddotazy, pokud nenalezen žádný řádek v poddotazu se sloupec aktualizuje na NULL, což téměř vždy není to, co chcete. V mém aktualizovaném dotazu se řádek aktualizuje pouze v případě, že je nalezen odpovídající řádek. Jinak se řádek nedotkne.

Normálně byste nechtěli aktualizovat řádky, když se ve skutečnosti nic nemění. To je drahé nic nedělat (ale stále vytváří mrtvé řady). Poslední výraz v WHERE klauzule brání takovým prázdným aktualizacím :

     AND   c.customer_id IS DISTINCT FROM sub.store_key

Související:

  • Jak mohu (nebo mohu) SELECT DISTINCT na více sloupcích?


  1. Jak používat _COUNT v BaseColumns

  2. Jak RADIANS() funguje v MariaDB

  3. Postgres datum překrývající se omezení

  4. Funkce MySQL MOD() – Proveďte modulo operaci v MySQL