sql >> Databáze >  >> RDS >> SQLite

Jak vytvořit vypočítaný sloupec v SQLite

Podpora vygenerovaných sloupců byla přidána do SQLite ve verzi 3.31.0, která byla vydána 22. ledna 2020.

Vygenerované sloupce a vypočítané sloupce jsou to samé. Jsou to sloupce, jejichž hodnoty jsou funkcí jiných sloupců ve stejném řádku.

V SQLite se generované sloupce vytvářejí pomocí GENERATED ALWAYS column-constraint při vytváření nebo změně tabulky.

Existují dva typy generovaných sloupců; STORED a VIRTUAL . Pouze VIRTUAL sloupce lze přidat při změně tabulky. Oba typy lze přidat při vytváření tabulky.

Příklad

Zde je příklad k demonstraci.

CREATE TABLE Products( 
    Id INTEGER PRIMARY KEY, 
    Name TEXT,
    Qty INT,
    Price INT,
    TotalValue INT GENERATED ALWAYS AS (Qty * Price)
);

Pokud se zobrazí následující chyba:

Error: near "AS": syntax error

Je pravděpodobné, že budete muset upgradovat na novější verzi SQLite. Generované sloupce byly zavedeny až v SQLite 3.31.0.

Nyní vložíme data a vybereme je.

INSERT INTO Products VALUES 
  (1, 'Hammer', 10, 9.99),
  (2, 'Saw', 5, 11.34),
  (3, 'Wrench', 7, 37.00),
  (4, 'Chisel', 9, 23.00),
  (5, 'Bandage', 70, 120.00);

SELECT * FROM Products;

Výsledek:

Id     Name        Qty    Price   TotalValue
-----  ----------  -----  ------  ----------
1      Hammer      10     9.99    99.9      
2      Saw         5      11.34   56.7      
3      Wrench      7      37      259       
4      Chisel      9      23      207       
5      Bandage     70     120     8400      

Toto je jednoduchý příklad a určitě můžete použít složitější výrazy, například takové, které využívají vestavěné funkce.

Virtuální vs. uložený

Ve výchozím nastavení je vypočítaný sloupec vytvořen jako VIRTUAL sloupec.

Máte také možnost vytvořit STORED sloupec.

Hodnota VIRTUAL sloupec se vypočítá při čtení, zatímco hodnota STORED sloupec se vypočítá při zápisu řádku.

Můžete explicitně použít VIRTUAL nebo STORED v definici sloupce označte, který by to měl být. Pokud toto vynecháte, bude to VIRTUAL .

Zde je návod, jak můžeme změnit předchozí příklad na použití STORED sloupec.

CREATE TABLE Products( 
    Id INTEGER PRIMARY KEY, 
    Name TEXT,
    Qty INT,
    Price INT,
    TotalValue INT GENERATED ALWAYS AS (Qty * Price) STORED
);

Bez ohledu na to, zda se jedná o STORED sloupec nebo VIRTUAL , zadávání a výběr dat je úplně stejný.

INSERT INTO Products VALUES 
  (1, 'Hammer', 10, 9.99),
  (2, 'Saw', 5, 11.34),
  (3, 'Wrench', 7, 37.00),
  (4, 'Chisel', 9, 23.00),
  (5, 'Bandage', 70, 120.00);

SELECT * FROM Products;

Výsledek:

Id     Name        Qty    Price   TotalValue
-----  ----------  -----  ------  ----------
1      Hammer      10     9.99    99.9      
2      Saw         5      11.34   56.7      
3      Wrench      7      37      259       
4      Chisel      9      23      207       
5      Bandage     70     120     8400      

Aktualizace dat ve vygenerovaném sloupci

Data nelze aktualizovat přímo ve vypočítaném sloupci. To znamená, že nemůžete zapisovat přímo do samotného vypočítaného sloupce.

Chcete-li aktualizovat jeho data, musíte aktualizovat data v podkladových sloupcích, které se používají ve výrazu vypočítaného sloupce.

Zde je příklad aktualizace dat použitých v předchozích příkladech.

UPDATE Products 
SET Qty = 5 WHERE Id = 1;

SELECT * FROM Products;

Výsledek:

Id     Name        Qty    Price   TotalValue
-----  ----------  -----  ------  ----------
1      Hammer      5      9.99    49.95     
2      Saw         5      11.34   56.7      
3      Wrench      7      37      259       
4      Chisel      9      23      207       
5      Bandage     70     120     8400      

V tomto případě jsem snížil počet dostupných kladiv na 5. To zase snížilo celkovou hodnotu kladiv na skladě a hodnotu ve vygenerovaném sloupci (TotalValue ) snížena z 99,99 na 49,95.


  1. MySQL - length() vs char_length()

  2. 4 Funkce, které vracejí minuty z časové hodnoty v MariaDB

  3. Proč nemohu vyloučit závislé sloupce ze „GROUP BY“, když agreguji podle klíče?

  4. Seskupení podle klauzule v mySQL a postgreSQL, proč chyba v postgreSQL?