4
votes

MySQL - la mise à jour avec jointure interne crée des valeurs nulles

J'essaye de faire une mise à jour des valeurs d'une table de stock dans une autre table de stock. Cependant, certaines valeurs sont copiées sous la forme NULL car ce stock n'existe pas dans la table source. Je pensais que INNER JOIN ne regardait que les valeurs partagées entre les deux tables. Ma table allStocks a beaucoup plus de stocks que divStocks , mais il y a quelques stocks dans divStocks qui n'existent pas dans allStocks . Je veux juste copier les prix de allStocks dans divStocks et ne pas écraser les prix avec NULL .

Voici ma requête actuelle:

UPDATE `divStocks` ds INNER JOIN `allStocks` als ON
`ds`.`tickerSymbol` = `als`.`tickerSymbol` SET `ds`.`price` =
`als`.`price`, `ds`.`priceAsOf` = `als`.`priceAsOf`;


9 commentaires

Êtes-vous sûr que le symbole du ticker n'existe pas des deux côtés et que c'est juste le prix qui manque?


Le ticker n'existe pas dans la table source ( allStocks ) donc le prix devient NULL dans divStocks .


"ne remplacez aucun prix par NULL" - Voulez-vous dire que si divStocks a déjà un prix NULL, ne le changez pas? (Je suppose que vous vouliez dire autre chose.)


Je veux dire avant la requête, le prix en divStocks est une décimale spécifique, ex: 34.02. Après la requête si ce ticker n'existe pas dans allStocks , ce prix est écrasé par NULL .


Veuillez publier des exemples de données pour démontrer votre problème.


Il s'agit d'un INNER JOIN , donc si ds.tickerSymbol ne correspond pas dans allStocks , la ligne n'est pas mise à jour. Vérifiez donc vos données car le problème se situe peut-être ailleurs.


Dah! Peu importe, j'effaçais moi-même les valeurs! Je vais fermer ça, désolé les gars!


je me demande votre als. tickerSymbol a des lignes dupliquées contenant des données nulles.


S'il vous plaît dans les questions de code, donnez un exemple minimal reproductible --cut & paste & runnable code; exemple d'entrée avec sortie souhaitée et réelle (y compris les messages d'erreur verbatim); balises et spécification et explication claires. Cela inclut le moins de code que vous puissiez donner, c'est-à-dire que le code que vous montrez est OK étendu par le code que vous montrez n'est pas OK. (Débogage fondamental.) Veuillez formater votre code de manière raisonnable. Lisez l'aide à l'édition concernant les blocs de code. Veuillez clarifier via des modifications, pas des commentaires.


4 Réponses :


0
votes

Vous pouvez utiliser COALESCE pour gérer les cas où les valeurs de allStocks sont nulles.

UPDATE `divStocks` ds 
INNER JOIN `allStocks` als ON `ds`.`tickerSymbol` = `als`.`tickerSymbol` 
SET `ds`.`price` = COALESCE(`als`.`price`,`ds`.`price`)
   ,`ds`.`priceAsOf` = COALESCE(`als`.`priceAsOf`,`ds`.`priceAsOf`);


0 commentaires

0
votes

Si vous souhaitez mettre à jour des enregistrements de la table divStocks qui n'existent que dans la table allStocks , vous devez utiliser RIGHT JOIN au lieu de INNER REJOIGNEZ . Par exemple:

UPDATE `divStocks` ds 
RIGHT JOIN `allStocks` als ON `ds`.`tickerSymbol` = `als`.`tickerSymbol` 
SET `ds`.`price` = `als`.`price`, `ds`.`priceAsOf` = `als`.`priceAsOf`;


0 commentaires

3
votes

Je dirais que la solution la plus simple serait d'ajouter un WHERE à votre requête pour exclure spécifiquement les lignes qui n'ont pas de prix dans la table allStocks . Le faire de cette façon ajoute à la lisibilité de la requête par rapport à l'utilisation de quelque chose comme un RIGHT JOIN qui est assez rare.

UPDATE `divStocks` ds 
INNER JOIN `allStocks` als ON `ds`.`tickerSymbol` = `als`.`tickerSymbol` 
SET `ds`.`price` = `als`.`price`, `ds`.`priceAsOf` = `als`.`priceAsOf`
WHERE `als`.`price` IS NOT NULL;


0 commentaires

0
votes

IFNULL? C'est SI vous souhaitez conserver en tant que jointure interne

UPDATE `divStocks` ds 
INNER JOIN `allStocks` als ON`ds`.`tickerSymbol` = `als`.`tickerSymbol`
SET `ds`.`price` = IFNULL(`als`.`price`, `ds`.`priceAsOf`), 
`ds`.`priceAsOf` = IFNULL(`als`.`priceAsOf`, `ds`.`priceAsOf`);


0 commentaires