PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 09/10/2011 19:33:45

guk92
Membre

Jointures avec les requêtes UPDATE sous PostgreSQL

Bonsoir,


Venant de SQL Server, je sais qu'il est possible de faire des jointures sur des requêtes UPDATE, mais sous PostgreSQL mes tests n'ont rien donnés.

Pour vous montrer un exemple, une requête ayant cette syntaxe fonctionne sous SQL Server :

UPDATE monAliasTable1
SET 
monAliasTable1.colonneCount = monAliasTable2.monCount,
monAliasTable1.colonneMax = monAliasTable2.monMax,
monAliasTable1.colonneMin = monAliasTable2.monMin
FROM test.dbo.Table1 AS monAliasTable1
/* JOINTURES POSSIBLES */
INNER JOIN (SELECT COUNT(*) AS monCount, MAX(val) AS monMax, MIN(val) AS monMin FROM test.dbo.Table2) AS monAliasTable2
ON monAliasTable1.id = 1;

Ceci n'est qu'un bref exemple, mais il est ainsi possible de faire des requêtes UPDATE avec des jointures dans SQL Server, ce qui peut-être très efficace lorsqu'on souhaite regrouper un maximum de résultat à partir d'une seule requête.

J'ai essayé de faire la même chose sous PostgreSQL mais cela n'a rien donnée, pourtant dans la documentation il est possible d'ajouter FROM :

UPDATE [ ONLY ] table SET colonne = { expression | DEFAULT } [, ...]
    [ FROM liste_from ]
    [ WHERE condition ]

J'ai donc plusieurs questions qui me trottent en tête :
1. Est-ce qu'il est possible de faire des requêtes UPDATE pouvant contenir des jointures comme sous SQL Server ? Si oui puis-je avoir un exemple ? big_smile
2. Est-ce que cette technique ( que je trouve personnellement très efficace cool ) fait parti de la norme SQL ? yikes



Autrement sous SQL Server, il est possible d'avoir cette syntaxe :

DELETE t1 FROM test.dbo.Table1 AS t1 ...

Cette forme ne fonctionne-t-elle vraiment pas sous PostgreSQL ou sinon c'est moi qui m'y prend mal ? big_smile
Si cela ne fonctionne pas sous PostgreSQL je suppose que cette syntaxe ne doit pas faire parti de la norme ? (enfin je pense).



Merci et bonne soirée. smile

Hors ligne

#2 09/10/2011 19:47:25

gleu
Administrateur

Re : Jointures avec les requêtes UPDATE sous PostgreSQL

1. Si, c'est possible. Par contre, difficile de donner un exemple sans idée particulière et j'avoue que je suis plutôt sec.
2. Non, la partie FROM est une extension PostgreSQL. Voir http://docs.postgresql.fr/9.1/sql-update.html
3. Non, ça ne fonctionne pas. Par contre, j'avoue que cette écriture me paraît alambiquée. Il est beaucoup plus simple de faire un "DELETE FROM table1 AS t1...". (oui, j'abandonne directement le test.dbo.Table1 qui ne fonctionne pas sous PostgreSQL). Voir http://docs.postgresql.fr/9.1/sql-delete.html .


Guillaume.

Hors ligne

#3 09/10/2011 20:07:04

rjuju
Administrateur

Re : Jointures avec les requêtes UPDATE sous PostgreSQL

Je pense que le problème vient du

UPDATE alias 
...
FROM table AS alias

Vous devriez plutôt faire :

UPDATE table as ALIAS ....
FROM
et JOIN si besoin
et ça devrait résoudre le problème.

Hors ligne

#4 09/10/2011 22:47:41

dverite
Membre

Re : Jointures avec les requêtes UPDATE sous PostgreSQL

L'update en question pourrait s'écrire à peu près comme ça avec postgres:

UPDATE Table1
SET colonneCount=s.monCount, colonneMax=s.monMax,  colonneMin =s.monCount
FROM (SELECT COUNT(*) AS monCount, MAX(val) AS monMax, MIN(val) AS monMin FROM Table2) s
WHERE id = 1;

Et la version standard passe-partout serait plutôt:

UPDATE Table1
SET colonneCount =  (SELECT COUNT(*) from Table2),
colonneMax= (SELECT MAX(val) from Table2),
colonneMin= (SELECT MIN(val) from Table2)
WHERE id=1;

Hors ligne

#5 09/10/2011 23:48:15

guk92
Membre

Re : Jointures avec les requêtes UPDATE sous PostgreSQL

Je vous remercie pour vos réponse smile

En effet, après avoir vu la syntaxe sur la possibilité de faire une jointure avec un UPDATE sur PostgreSQL de Rjuju j'en suis arrivé au même résultat que Dverite.

@Rjuju
La syntaxe suivante fonctionne :

UPDATE table as ALIAS ....
SET colonne = ...

FROM table
-- et JOIN si besoin

... mais je pense qu'elle est inutile car l'ALIAS ne sert à rien hmm
Ceci provoque une erreur :

UPDATE table as ALIAS ....
SET [b]ALIAS.colonne[/b] = ...

FROM table
-- et JOIN si besoin

@Dverite
Pour ce qui est de la version Standard, il est plus simple à comprendre certes, mais il nécessite de créer autant de requête que de champ à mettre à jour, c'est très gênant quand on cherche à optimiser (c'est le but recherché de cette technique en faite).

Cette "technique" ne fait pas parti de la norme SQL à ce que j'ai compris, par contre je comprend le fait que PostgreSQL l'ait ajouté, car il peut être très utile ( et fera peut-être parti du Standard SQL un jour big_smile ).

Pour finir j'ai trouvé un compromis entre SQL Server et PostgreSQL, il est en effet possible d'utiliser la syntaxe suivante pour les deux SGBD (copier/coller de Dverite) :

UPDATE Table1
SET colonneCount=s.monCount, colonneMax=s.monMax,  colonneMin =s.monCount
FROM (SELECT COUNT(*) AS monCount, MAX(val) AS monMax, MIN(val) AS monMin FROM Table2) s
WHERE Table1.id = 1;

Pour ce qui est de SQL Server, il est possible de faire "UPDATE alias" (ce que j'avais l'habitude de faire) ou le nom de la table "UPDATE table" (ce que fait uniquement PostgreSQL, et c'est pas plus mal smile ).

Dernière modification par guk92 (10/10/2011 00:23:15)

Hors ligne

#6 10/10/2011 15:09:41

SQLpro
Membre

Re : Jointures avec les requêtes UPDATE sous PostgreSQL

Un exemple :

CREATE TABLE T1 (A INT, B INT, C INT);

CREATE TABLE T2 (A INT, B INT, D INT);

INSERT INTO T1 VALUES (10, 20, 99), (11, 21, 33);

INSERT INTO T2 VALUES (10, 20, 0), (11, 21, 0);

UPDATE T1
SET    C = T2.D
FROM   T2
WHERE  T1.A = T2.A
  AND  T1.B = T2.B
  AND  C < 50

SELECT * FROM T1
A     B     C
----- ----- -----
10    20    99
11    21    0

la principe est le même que dans SQL Server, mais comme la norme SQL interdit l'utilisation d'un alias pour la table cible d'une mise à jour et que PostGreSQL respecte ceci à la lettre, il faut tout simplement reprendre intégralement le nom de la table cible.

A +


Frédéric Brouard, alias SQLpro,  ARCHITECTE DE DONNÉES,  Expert langage SQL
Le site sur les SGBD relationnel et langage SQL   : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA, ISEN Toulon,  CESI Aix en Provence  * * * * *

Hors ligne

#7 10/10/2011 15:19:40

rjuju
Administrateur

Re : Jointures avec les requêtes UPDATE sous PostgreSQL

L'alias est interdit pour les SET mais absolument pas dans le WHERE.

Hors ligne

Pied de page des forums