web-dev-qa-db-fra.com

Colonne calculée à partir d'une autre colonne?

Étant donné le tableau suivant:

id | value
--------------
1     6
2     70

Est-il possible d'ajouter une colonne automatiquement calculée en fonction d'une autre colonne de la même table? Comme une vue, mais une partie de la même table. Par exemple, calculated serait la moitié de value. Calculated devrait être automatiquement mis à jour lorsque value change, comme le serait une vue.

Le résultat serait:

id | value | calculated
-----------------------
1     6       3
2     70      35
49
Matthew

La colonne générée est l’une des bonnes approches pour la version MySql qui est 5.7.6 et plus. 

Il existe deux types de colonnes générées: 

  • Virtual (valeur par défaut) - la colonne sera calculée à la volée lorsqu'un enregistrement Est lu à partir d'une table 
  • Stocké - la colonne sera calculée quand un enregistrement new est écrit/mis à jour dans la table

Les deux types peuvent avoir des restrictions NOT NULL, mais seule une colonne générée stockée peut faire partie d'un index.

Pour le cas actuel, nous allons utiliser la colonne générée stockée. Pour mettre en œuvre, j’ai considéré que les deux valeurs requises pour le calcul sont présentes dans le tableau

CREATE TABLE order_details (price DOUBLE, quantity INT, amount DOUBLE AS (price * quantity));

INSERT INTO order_details (price, quantity) VALUES(100,1),(300,4),(60,8);

montant apparaîtra automatiquement dans le tableau et vous pourrez y accéder directement. Notez également que chaque fois que vous mettrez à jour une colonne, le montant sera également mis à jour.

39
Abhishek Gupta

Si c'est une sélection, vous pouvez le faire comme:

SELECT id, value, (value/2) AS calculated FROM mytable

Sinon, vous pouvez également modifier la table pour ajouter la colonne manquante, puis effectuer une requête UPDATE pour calculer les valeurs de la nouvelle colonne comme suit:

UPDATE mytable SET calculated = value/2;

Si cela doit être automatique et que votre version de MySQL le permet, vous pouvez essayer avec triggers

31

MySQL 5.7 supporte les colonnes calculées. Ils l'appellent "colonnes générées" et la syntaxe est un peu étrange, mais elle supporte les mêmes options que celles que je vois dans d'autres bases de données.

https://dev.mysql.com/doc/refman/5.7/fr/create-table.html#create-table-generated-columns

24
Jonathan Allen

La réponse de @ krtek va dans la bonne direction, mais présente quelques problèmes.

La mauvaise nouvelle est que l’utilisation de UPDATE dans un déclencheur de la même table ne fonctionnera pas. La bonne nouvelle est que ce n'est pas nécessaire. vous pouvez opérer sur un NOUVEAU objet avant même que la table ne soit touchée.

La gâchette devient:

CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
  FOR EACH ROW BEGIN
    SET NEW.calculated = NEW.value/2;
  END;

Notez également que BEGIN ... END; La syntaxe doit être analysée avec un délimiteur différent. Le Shebang entier devient:

DELIMITER |

CREATE TRIGGER halfcolumn_insert BEFORE INSERT ON my_table
  FOR EACH ROW BEGIN
    SET NEW.calculated = NEW.value/2;
  END;
|

CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
  FOR EACH ROW BEGIN
    SET NEW.calculated = NEW.value/2;
  END;
|

DELIMITER ;
21
Jerry

Si vous souhaitez ajouter une colonne à votre table qui est automatiquement mise à jour à la moitié d'une autre colonne, vous pouvez le faire avec un déclencheur.

Mais je pense que la réponse déjà proposée est un meilleur moyen de le faire.

Déclencheur à code sec:

CREATE TRIGGER halfcolumn_insert AFTER INSERT ON table
  FOR EACH ROW BEGIN
    UPDATE table SET calculated = value / 2 WHERE id = NEW.id;
  END;
CREATE TRIGGER halfcolumn_update AFTER UPDATE ON table
  FOR EACH ROW BEGIN
    UPDATE table SET calculated = value / 2 WHERE id = NEW.id;
  END;

Je ne pense pas que vous puissiez déclencher un seul déclencheur, car les événements auxquels nous devons répondre sont différents.

4
krtek

J'espère que cela aide toujours quelqu'un comme beaucoup de gens pourraient arriver à cet article. Si vous avez besoin d'une colonne calculée, pourquoi ne pas simplement exposer vos colonnes souhaitées dans une vue? Ne vous contentez pas de sauvegarder des données ou de surcharger les performances avec des déclencheurs… exposez simplement les données dont vous avez besoin déjà formatées/calculées dans une vue.

J'espère que cela t'aides...

3
Doron

Vous pouvez utiliser les colonnes générées à partir de MYSQL 5.7.

Exemple d'utilisation:

ALTER TABLE tbl_test
ADD COLUMN calc_val INT 
GENERATED ALWAYS AS (((`column1` - 1) * 16) + `column2`) STORED;

VIRTUEL/ENREGISTRÉ 

  • Virtual: calculé à la volée lorsqu'un enregistrement est lu à partir d'une table (par défaut)
  • Stocké: calculé lorsqu'un nouvel enregistrement est inséré/mis à jour dans la table
0
PodTech.io