2009-05-07 7 views
1

Est-il possible de faire un select dans une instruction IF dans ON DUPLICATE KEY UPDATE? Disons que je veux configurer les tarifs d'expédition par code postal, et en cas de code postal en double entré, je veux appliquer le taux le plus élevé à appliquer.Sous-sélection MySQL dans ON DUPLICATE KEY

Ma base de données contient un tableau des tarifs d'expédition et un tableau des codes postaux. La table de code postal a une clé étrangère référençant les taux d'expédition, et le code postal qui a un index unique.

Lorsqu'il y a une clé en double, je souhaite définir l'ID du taux d'expédition sur le taux le plus élevé. Quelque chose comme ceci:

INSERT INTO ZipCodes (ShippingRateID, Zip) VALUES (11, '13754') ON DUPLICATE KEY UPDATE ShippingRateID = IF((SELECT Rate FROM ShippingRates sr WHERE sr.ShippingRateID = ShippingRateID) > [current rate], ShippingRateID, VALUES(ShippingRateID))

Lorsque je tente d'exécuter cette requête, MySQL me dit « sous-requête retourné plus d'un enregistrement ». Étant donné qu'il n'y a qu'un seul enregistrement correspondant dans la table ShippingRates, je ne comprends pas comment plus d'un enregistrement a été retourné. Ce qui se passe réellement, c'est que dans la sous-sélection, ShippingRateID fait toujours référence à la table ShippingRates, et le ShippingRateID de l'insert n'est pas utilisé. Donc, sans utiliser LIMIT, tous les tarifs d'expédition sont retournés. Si j'utilise LIMIT 1, j'obtiendrai toujours le premier taux, ce qui est faux.

Comment puis-je dire au sous-select d'utiliser ShippingRateID à partir de l'insert?

Répondre

2
INSERT INTO ZipCodes 
(ShippingRateID, Zip) 
VALUES (11, '13754') 
ON DUPLICATE KEY 
UPDATE ShippingRateID = 
    (SELECT IF(Rate > [current rate], ShippingRateID, VALUES(ShippingRateID)) 
     FROM (
      SELECT ShippingRateID AS AltID, Rate 
      FROM ShippingRates 
     ) AS sr 
     WHERE sr.AltID = ShippingRateID 
     LIMIT 1 
    ) 
+0

En quoi votre mise à jour est-elle différente de la mienne? – Yisroel

+0

Il protège contre le problème (non-sens) de récupération de lignes multiples et permet de récupérer le ShippingRateID de la table. – chaos

+0

J'ai testé votre mise à jour, elle le mettra toujours au taux le plus élevé de l'un des tarifs d'expédition, pas le plus élevé des 2 taux qui peuvent s'appliquer. Je ne vois pas pourquoi la LIMIT devrait être nécessaire du tout, quand la clause WHERE ne peut correspondre qu'à une ligne. S'il correspond à plus d'une ligne, il est clair que ShippingRateID n'est pas transmis correctement à la sous-sélection. – Yisroel

Questions connexes