PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Errore Postgres:più di una riga restituita da una sottoquery utilizzata come espressione

Tecnicamente , per riparare il tuo estratto conto, puoi aggiungere LIMIT 1 alla sottoquery per garantire che venga restituita al massimo 1 riga. Ciò eliminerebbe l'errore, il tuo codice sarebbe comunque una sciocchezza.

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

In pratica , vuoi abbinare le righe in qualche modo invece di selezionare una riga arbitraria dalla tabella remota store per aggiornare ogni riga della tua tabella locale customer .
La tua domanda rudimentale non fornisce dettagli sufficienti, quindi presumo una colonna di testo match_name in entrambe le tabelle (e UNIQUE nel store ) per il bene di questo esempio:

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

Ma è un modo estremamente costoso di fare le cose.

Idealmente , riscrivi completamente la dichiarazione.

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;

Questo risolve una serie di problemi nella tua dichiarazione originale.

Ovviamente, il problema di base che porta al tuo errore è stato corretto.

In genere è meglio entrare in relazioni aggiuntive nel FROM clausola di un UPDATE istruzione piuttosto che eseguire sottoquery correlate per ogni singola riga.

Quando si utilizza dblink, quanto sopra diventa mille volte più importante. Non vuoi chiamare dblink() per ogni singola riga, è estremamente costoso . Chiamalo una volta per recuperare tutte le righe di cui hai bisogno.

Con sottoquery correlate, se nessuna riga trovata nella sottoquery, la colonna viene aggiornata a NULL, che quasi sempre non è ciò che desideri. Nella mia query aggiornata, la riga viene aggiornata solo se viene trovata una riga corrispondente. Altrimenti, la riga non viene toccata.

Normalmente, non vorresti aggiornare le righe, quando in realtà non cambia nulla. Questo non fa nulla in modo costoso (ma produce comunque file morti). L'ultima espressione nel WHERE la clausola impedisce tali aggiornamenti vuoti :

     AND   c.customer_id IS DISTINCT FROM sub.store_key

Correlati:

  • Come faccio (o posso) SELEZIONARE DISTINCT su più colonne?