2016-01-12 2 views
0

J'ai une table Table1, dans le format suivant:ne peut pas utiliser une requête de sélection pour obtenir le nombre de jours en fonction DATEADD

Country No_Of_Days 
    XX   5 
    YY   10 

Et je dois mettre à jour la colonne de date_fin dans une autre table, Tableau 2, qui a une start_date en ajoutant les jours dans le tableau ci-dessus mentionné à date_début:

Country  Start_Date  End_Date Calc_Manual_Flag 
    XX  25-Dec-16  30-Dec-16  CALC 
    YY  02-Jan-17  12-Jan-17  CALC 

J'utilise la requête suivante, mais il ne semble pas fonctionner:

UPDATE dbo.Table2 
SET End_date = 
dateadd(
     day, 
     (SELECT No_Of_Days FROM Table1 WHERE Table2.Country = Table1.Country),Start_Date), 
    Calc_Manual_Flag = 'CALC' 
WHERE Table2.End_Date IS NULL 
AND Table2.Start_Date IS NOT NULL 

Mais cela ne semble pas fonctionner correctement. Les mises à jour ne semblent pas se passer comme prévu. Je reçois le message d'erreur suivant:

Msg 512, Level 16, State 1, Line 1 
Subquery returned more than 1 value. This is not permitted when the subquery  follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 

Veuillez fournir des conseils à ce sujet.

+0

Qu'est-ce qui se passe? –

+0

Qu'est-ce qui ne fonctionne pas correctement? Avez-vous des erreurs? Des valeurs inattendues? –

+0

Je reçois le message 0 lignes mises à jour – Manus

Répondre

1

je ferais cette requête en utilisant une JOIN explicite:

UPDATE t2 
    SET End_date = DATEADD(day, t1.No_Of_Days, t2.Start_Date) 
     Calc_Manual_Flag = 'CALC' 
    FROM dbo.Table2 t2 JOIN 
     Table1 t1 
     ON t2.Country = t1.Country 
    WHERE t2.End_Date IS NULL AND t2.Start_Date IS NOT NULL; 

Vous pouvez utiliser un LEFT JOIN si vous voulez vraiment mettre à jour les lignes où il n'y a pas de match.

Ceci corrige la cause proximale du problème, qui est dû à plusieurs lignes correspondantes dans Table11. Une correspondance arbitraire est utilisée pour la mise à jour.

Pour vraiment résoudre le problème, vous devez décider quoi faire. Si vous voulez soustraire tous les jours correspondant, puis global avant de rejoindre:

UPDATE t2 
    SET End_date = DATEADD(day, t1.No_Of_Days, t2.Start_Date) 
     Calc_Manual_Flag = 'CALC' 
    FROM dbo.Table2 t2 JOIN 
     (SELECT Country, SUM(No_Of_Days) as No_Of_Days 
      FROM Table1 t1 
      GROUP BY Country 
     ) t1 
     ON t2.Country = t1.Country 
    WHERE t2.End_Date IS NULL AND t2.Start_Date IS NOT NULL; 
+0

Bonjour Gordon. Merci pour la réponse. Est-ce que cela fonctionnera même après que le nouveau message d'erreur que j'ai mis en place soit affiché concernant la sous-requête? – Manus

+0

Bonjour Gordon, j'ai testé votre solution. Cela me donne de bons résultats. Mais une chose étrange est qu'il ne met pas à jour certains pays au hasard même si Start_Date n'est pas nul et le pays est dans le tableau 1 – Manus

+0

Excuses Gordon. Ma Table1 manquait quelques pays. D'où la pas de mise à jour. Mais sinon votre requête fonctionne magnifiquement. Merci pour l'aide – Manus

1

message d'erreur indique clairement que Country a des doublons dans la table d'abord si vous avez besoin de savoir ce que vous voulez faire avec des lignes en double soit sum le no_of_days ou prendre no_of_days basé sur une certaine commande

UPDATE t2 
SET End_date = Dateadd(day, t1.no_of_days, t2.start_date), 
     Calc_Manual_Flag = 'CALC' 
FROM dbo.table2 t2 
     CROSS apply (SELECT TOP 1 no_of_days --sum(no_of_days) 
        FROM table1 t1 
        WHERE t2.country = t1.country 
        ORDER BY somecol) cs 
WHERE t2.end_date IS NULL 
     AND t2.start_date IS NOT NULL 
+0

Merci pour l'aide VR46. Je suis allé avec la solution de Gordon. – Manus