UPDATE
UPDATE
Primary Key テーブルの行を更新します。
バージョン 3.0 より前のバージョンでは、UPDATE ステートメントは単一テーブルの更新のみをサポートし、共通テーブル式 (CTE) はサポートされていません。バージョン 3.0 以降、StarRocks は構文を拡張して、複数テーブルの結合と CTE をサポートします。更新するテーブルを他のテーブルと結合する必要 がある場合は、FROM 句または CTE でこれらの他のテーブルを参照することができます。バージョン 3.1 以降、UPDATE ステートメントは列モードでの部分更新をサポートし、少数の列に対して大量の行が関与するシナリオでは、更新速度が向上します。
このコマンドを実行するには、更新したいテーブルに UPDATE 権限が必要です。
使用上の注意
複数のテーブルを含む UPDATE ステートメントを実行する場合、StarRocks は UPDATE ステートメントの FROM 句のテーブル式を等価な JOIN クエリステートメントに変換します。したがって、UPDATE ステートメントの FROM 句で指定したテーブル式がこの変換をサポートしていることを確認してください。たとえば、UPDATE ステートメントが 'UPDATE t0 SET v1=t1.v1 FROM t1 WHERE t0.pk = t1.pk;' の場合、FROM 句のテーブル式は 't0 JOIN t1 ON t0.pk=t1.pk;' に変換できます。StarRocks は JOIN クエリの結果セットに基づいて更新するデータ行をマッチングします。ある行を更新するためには、結果セットの複数の行が特定の行にマッチングする可能性があります。このシナリオでは、これら複数の行の中からランダムな行の値に基づいてその行が更新されます。
構文
単一テーブルの更新
WHERE 条件を満たす場合、更新するテーブルのデータ行の指定された列に新しい値が割り当てられます。
[ <with_query>, ... ]
UPDATE <table_name>
SET <column_name> = <expression>, ...
WHERE <where_condition>
複数テーブルの更新
マルチテーブルの結合結果セットが更新するテーブルにマッチングされます。更新するテーブルのデータ行が結果セットとマッチし、WHERE 条件を満たす場合、指定された列のこれらのデータ行に新しい値が割り当てられます。
[ <with_query>, ... ]
UPDATE <table_name>
SET <column_name> = <expression>, ...
[ FROM <from_item>, ... ]
WHERE <where_condition>
パラメータ
with_query
UPDATE ステートメントで参照できる 1 つ以上の CTE。CTE は複雑なステートメントの可読性を向上させることができる一時的な結果セットです。
table_name
更新するテーブルの名前です。
column_name
更新する列の名前です。テーブル名を含めることはできません。たとえば、'UPDATE t1 SET col = 1' は無効です。
expression
列に新しい値を割り当てる式です。
from_item
データベース内の他の 1 つ以上のテーブルです。これらのテーブルは、WHERE 句で指定した条件に基づいて更新するテーブルと結合することができます。結果セットの行の値は、更新するテーブルのマッチする行の指定された列の値を更新するために使用されます。たとえば、FROM 句が FROM t1 WHERE t0.pk = t1.pk
の場合、StarRocks は UPDATE ステートメントを実行するときに FROM 句のテーブル式を t0 JOIN t1 ON t0.pk=t1.pk
に変換します。
where_condition
行を更新するための条件です。WHERE 条件を満たす行のみが更新されます。このパラメータは必須です。なぜなら、テーブル全体を誤って更新することを防ぐのに役立つからです。テーブル全体を更新したい場合は、'WHERE true' を使用することができます。ただし、列モードでの部分更新の場合はこのパラメータは必要ありません。
列モードでの部分更新 (バージョン 3.1 より)
列モードでの部分更新は、少数の列を更新するが多数の行が関与するシナリオに適しています。このようなシナリオでは、列モードを有効にすることで更新速度が向上します。たとえば、100 列のテーブルで、全行に対して 10 列 (全体の 10%) のみが更新される場合、列モードの更新速度は 10 倍高速になります。
システム変数 partial_update_mode
は部分更新のモードを制御し、以下の値をサポートしています。
auto
(デフォルト): システムは UPDATE ステートメントと関連する列を分析し、部分更新のモードを自動的に決定します。以下の基準を満たす場合、システムは自動的に列モードを使用します:- 更新される列の割合が総列数の 30% 未満であり、更新される列の数が 4 つ未満である。
- 更新ステートメントが WHERE 条件を使用していない。 それ以外の場合、システムは列モードを使用しません。
column
: 部分更新に列モードを使用します。これは特に、少数の列と多数 の行が関与する部分更新に適しています。
EXPLAIN UPDATE xxx
を使用して部分更新のモードを表示することができます。
例
単一テーブルの更新
従業員情報を記録するための Employees
テーブルを作成し、テーブルに 5 つのデータ行を挿入します。
CREATE TABLE Employees (
EmployeeID INT,
Name VARCHAR(50),
Salary DECIMAL(10, 2)
)
PRIMARY KEY (EmployeeID)
DISTRIBUTED BY HASH (EmployeeID)
PROPERTIES ("replication_num" = "3");
INSERT INTO Employees VALUES
(1, 'John Doe', 5000),
(2, 'Jane Smith', 6000),
(3, 'Robert Johnson', 5500),
(4, 'Emily Williams', 4500),
(5, 'Michael Brown', 7000);
全従業員の給与を 10% 上げる場合、次のステートメントを実行できます。
UPDATE Employees
SET Salary = Salary * 1.1 -- 給与を 10% 上げる。
WHERE true;
平均給与よりも低い給与をもつ従業員に 10% の昇給を与える場合、次のステートメントを実行できます。
UPDATE Employees
SET Salary = Salary * 1.1 -- 給与を 10% 上げる。
WHERE Salary < (SELECT AVG(Salary) FROM Employees);
上記のステートメントを読みやすくするために、CTE を使用して以下のように書き直すこともできます。
WITH AvgSalary AS (
SELECT AVG(Salary) AS AverageSalary
FROM Employees
)
UPDATE Employees
SET Salary = Salary * 1.1 -- 給与を 10% 上げる。
FROM AvgSalary
WHERE Employees.Salary < AvgSalary.AverageSalary;
複数テーブルの更新
アカウント情報を記録するための Accounts
テーブルを作成し、テーブルに 3 つのデータ行を挿入します。
CREATE TABLE Accounts (
Accounts_id BIGINT NOT NULL,
Name VARCHAR(26) NOT NULL,
Sales_person VARCHAR(50) NOT NULL
)
PRIMARY KEY (Accounts_id)
DISTRIBUTED BY HASH (Accounts_id)
PROPERTIES ("replication_num" = "3");
INSERT INTO Accounts VALUES
(1,'Acme Corporation','John Doe'),
(2,'Acme Corporation','Robert Johnson'),
(3,'Acme Corporation','Lily Swift');
Employees
テーブルで Acme Corporation のアカウントを管理している従業員に 10% の昇給を与える場合、次のステートメントを実行できます。
UPDATE Employees
SET Salary = Salary * 1.1 -- 給与を 10% 上げる。
FROM Accounts
WHERE Accounts.name = 'Acme Corporation'
AND Employees.Name = Accounts.Sales_person;
上記のステートメントを読みやすくするために、CTE を使用して以下のように書き直すこともできます。
WITH Acme_Accounts as (
SELECT * from Accounts
WHERE Accounts.name = 'Acme Corporation'
)
UPDATE Employees SET Salary = Salary * 1.1 -- 給与を 10% 上げる。
FROM Acme_Accounts
WHERE Employees.Name = Acme_Accounts.Sales_person;