PostgreSQL - en Utilisant une sous-Requête pour mettre à Jour Plusieurs Valeurs de la Colonne
J'ai besoin d'être en mesure de mettre à jour plusieurs colonnes sur une table en utilisant le résultat d'une sous-requête. Un exemple simple permettra de présenter comme ci-dessous -
UPDATE table1
SET (col1, col2) =
((SELECT MIN (ship_charge), MAX (ship_charge) FROM orders))
WHERE col4 = 1001;
Comment puis-je faire dans PostgreSQL ?
Merci pour les conseils!
Mise à JOUR: je m'excuse pour la fabrication de l'échantillon trop simple pour mon réel de cas d'utilisation. La requête ci-dessous est plus précis -
UPDATE table1
SET (TOTAL_MIN_RATE, TOTAL_MAX_RATE) = (SELECT AVG(o.MIN_RATE), AVG(o.MAX_RATE)
FROM ORDR o INNER JOIN table2 ba ON (o.PAY_ACCT_ID = ba.ACCT_ID)
INNER JOIN table3 mb ON (ba.BANK_ID = mb.BANK_ID)
WHERE ba.CNTRY_ID = table1.CNTRY_ID AND
o.STUS_CD IN ('01','02','03','04','05','06') AND
((o.FRO_CRNCY_ID = table1.TO_CRNCY_ID AND o.TO_CRNCY_ID = table1.FRO_CRNCY_ID) OR
(o.TO_CRNCY_ID = table1.TO_CRNCY_ID AND o.FRO_CRNCY_ID = table1.FRO_CRNCY_ID))
GROUP BY ba.CNTRY_ID)
Vous devez vous connecter pour publier un commentaire.
Si vous voulez éviter les deux les sous-sélections, la requête peut être réécrite comme ceci:
Si ship_charge n'est pas indexé, cela devrait être plus rapide que les deux les sous-sélections. Si ship_charge est indexé, il n'a probablement pas faire une grande différence
Modifier
De départ avec Postgres 9.5 cela peut aussi être écrit comme:
Vous pouvez également retourner plusieurs lignes dans la sous-requête si vous souhaitez mettre à jour plusieurs lignes à la fois dans le tableau 1.
Ce n'est pas le moyen le plus efficace pour ce faire, mais c'est simple:
Une option (mais pas le seul), c'est d'utiliser deux sous-requêtes:
De la beaux-manuel de PostgreSQL 9.0 mise à JOUR:
Comme le document officiel dit: vous pouvez utiliser la mise à jour standard Synopsis de PostgreSQL mise à jour
UPDATE table
SET { column = { expression | DEFAULT } |
( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
[ FROM from_list ]
[ WHERE condition ]
De sorte que vous pouvez utiliser l'écrire comme ceci:
UPDATE table1
SET TOTAL_MIN_RATE = subQuery."minRate",
TOTAL_MAX_RATE = subQuery.maxRate
FROM
(
SELECT
AVG (o.MIN_RATE) AS minRate,
AVG (o.MAX_RATE) AS maxRate
FROM
ORDR o
INNER JOIN table2 ba ON (o.PAY_ACCT_ID = ba.ACCT_ID)
INNER JOIN table3 mb ON (ba.BANK_ID = mb.BANK_ID)
WHERE
ba.CNTRY_ID = table1.CNTRY_ID
AND o.STUS_CD IN (
'01',
'02',
'03',
'04',
'05',
'06'
)
AND (
(
o.FRO_CRNCY_ID = table1.TO_CRNCY_ID
AND o.TO_CRNCY_ID = table1.FRO_CRNCY_ID
)
OR (
o.TO_CRNCY_ID = table1.TO_CRNCY_ID
AND o.FRO_CRNCY_ID = table1.FRO_CRNCY_ID
)
)
GROUP BY
ba.CNTRY_ID
) subQuery;
Ou un moyen plus simple:
UPDATE table1
SET (
TOTAL_MIN_RATE,
TOTAL_MAX_RATE
) = (
SELECT
AVG (o.MIN_RATE) AS minRate,
AVG (o.MAX_RATE) AS maxRate
FROM
ORDR o
INNER JOIN table2 ba ON (o.PAY_ACCT_ID = ba.ACCT_ID)
INNER JOIN table3 mb ON (ba.BANK_ID = mb.BANK_ID)
WHERE
ba.CNTRY_ID = table1.CNTRY_ID
AND o.STUS_CD IN (
'01',
'02',
'03',
'04',
'05',
'06'
)
AND (
(
o.FRO_CRNCY_ID = table1.TO_CRNCY_ID
AND o.TO_CRNCY_ID = table1.FRO_CRNCY_ID
)
OR (
o.TO_CRNCY_ID = table1.TO_CRNCY_ID
AND o.FRO_CRNCY_ID = table1.FRO_CRNCY_ID
)
)
GROUP BY
ba.CNTRY_ID
);
À l'aide de
UPDATE FROM
est une bonne solution si vous n'avez pas simple les sous-sélections. Dans ceUPDATE
je voulais mettre l'event_profile_id
de laphotos
table pour être le propriétaire (cas des profils sont propriétaires) de la photo la photo appartient à.