SQL Server: instruction de mise à JOUR où MAX requête
Je suis en train de faire une migration de données dans SQL Server 2008 R2. Je suis un SQL-Serveur de noob, mais je sais Ingres et MySql assez bien.
J'ai besoin de "valeurs par défaut" pour les deux nouveaux champs à "valeurs actuelles" à partir d'une autre table. Voici ma première naïve tentative (comment je le ferais dans Ingres).
update rk_risk
set n_target_probability_ID = a.n_probability_ID
, n_target_consequence_ID = a.n_consequence_ID
from rk_assess a
WHERE a.n_assess_id = (
SELECT MAX(n_assess_id)
FROM rk_assess a2
WHERE a2.n_risk_id = a.n_risk_id
);
La requête ci-dessus s'exécute sans erreur dans la suite, mais elle définit TOUS la n_target_probability_ID & n_target_consequence_ID à la même valeur... que de la pure et simple de la dernière évaluation (comme revêtue de "la dernière évaluation DE CE RISQUE").
La rk_assess
table contient une histoire complète de dossiers d'évaluation pour rk_risk
s, et ma mission est de "défaut", la nouvelle cible de probabilité & conséquence de la colonne du risque tableau pour les valeurs de "l'actuel" (c'est à dire le dernier) dossier d'évaluation. Le rk_assess.n_assess_id
colonne auto-incrémentée (identificateur immuable une fois), donc le max-id doit toujours être le dernier enregistrement.
J'ai eu un peu de recherche, à la fois dans google et DONC, et j'ai essayé un peu différent de la version de la requête, mais je suis toujours bloqué. Voici un couple de d'autres épique échoue, avec des références.
update rk_risk
set n_target_probability_ID = (select a.n_probability_ID from rk_assess a where a.n_assess_id = (select max(n_assess_id) from rk_assess a2 where a2.n_risk_id = a.n_risk_id) as ca)
, n_target_consequence_ID = (select a.n_consequence_ID from rk_assess a where a.n_assess_id = (select max(n_assess_id) from rk_assess a2 where a2.n_risk_id = a.n_risk_id) as ca)
;
http://stackoverflow.com/questions/6256844/sql-server-update-from-select
update r
set r.n_target_probability_ID = ca.n_probability_ID
, r.n_target_consequence_ID = ca.n_consequence_ID
from rk_risk r
join rk_assess a
on a.n_risk_id = r.n_risk_id
select r.n_risk_id
, r.n_target_probability_ID, r.n_target_consequence_ID
, ca.n_probability_ID, ca.n_consequence_ID
from rk_risk r
join rk_assess a
on a.n_risk_id = r.n_risk_id
http://stackoverflow.com/questions/4024489/sql-server-max-statement-returns-multiple-results
UPDATE rk_risk
SET n_target_probability_ID = ca.n_probability_ID
, n_target_consequence_ID = ca.n_consequence_ID
FROM ( rk_assess a
INNER JOIN (
SELECT MAX(a2.n_assess_id)
FROM rk_assess a2
WHERE a2.n_risk_id = a.n_risk_id
) ca -- current assessment
Tous les pointeurs serait grandement apprécié. Je vous remercie tous à l'avance, même pour la lecture de ce jour.
Acclamations. Keith.
OriginalL'auteur corlettk | 2011-06-17
Vous devez vous connecter pour publier un commentaire.
Comment à ce sujet:
rk_assess.n_risk_id
Essayez la mise à jour ci-dessus, je crois que ce sera le travail. La clé est vous avez besoin d'une table dérivée (b) qui renvoie à la dernière évaluation pour chaque n_risk_id, alors vous pouvez vous joindre rk_assess sur le PK pour obtenir les données associées. Un sens?
J'ai essayé votre poing coupé, et il avait le même comportement que ma première tentative... c'est à dire tous ligne a obtenu des valeurs de la abolutute-dernière évaluation... j'ai essayé la version modifiée, et CELA FONCTIONNE!!! Je vous remercie donc beaucoup. J'ai été assez frustré, que ce que je pensait que ce serait facile, et n'a donc pas d'estimer les temps, s'est avéré être tellement difficile. Merci encore. Keith.
Génial, content que ça fonctionne pour vous! Aussi, prenez note des réponses ci-dessous par @Andrew Lazare et @Conrad Frix, à l'aide de
row_number()
, qui est une solution plus élégante si vous avez SQL Server 2005+. C'est très pratique surtout quand vous avez besoin pour obtenir un certain rang, basé sur d'autres critères que le min/max PK. Dans votre cas, vous avez juste besoin d'un max de PK, la valeur pour votre jointure, de sorte que les deux solutions fonctionnent dans ce cas.OriginalL'auteur Jerad Rose
si vous utilisez sql 2005 ou plus, vous pouvez en outre Jerad la réponse de l'utilisation de la fonction row_number
Ou de JOINTURE CROISÉE
OriginalL'auteur Conrad Frix
J'ai essayé cette, ressemble, il est de travail:
Merci pour la réponse... c'est une équipe de chose 😉
OriginalL'auteur Aziz Shaikh
J'ai découvert ce à partir d'une autre question, de SORTE qu'aujourd'hui. Le
UPDATE-FROM
de la construction n'est pas standard SQL, MySQL et non standard de la version est différente de Postgres non standard de la version. Le problème ici, c'est comme si SQL Server suit Postgres.Le problème, comme Jerad le souligne dans son édition, c'est qu'il n'y a pas de lien entre la table en cours de mise à jour et les tables dans la sous-requête. MySQL semble créer des jointure implicite ici (sur les noms de colonnes? dans l'autre exemple, c'est par le traitement de deux copies de la même table que le même, non séparées).
Je ne sais pas si SQL Server permet de fenêtrage dans la sous-requête, mais si c'est le cas, je pense que vous voulez
Je commence avec le fenêtrage et d'expressions de table communes de moi-même. Je pense qu'ils ne sont pas assez d'attention, car MySQL ne supporte pas.
OriginalL'auteur Andrew Lazarus