を介してこれを行うことはできませんUPDATE
が、できることは、一連のINSERT INTO ... SELECT
文字列リテラルを使用してDELETE
から、展開した行を削除することです。
/* First insert a row for each mon,tue,wed,thur,fri */
/* Column values are copied from the existing mon-fri row, and use the literal strings 'mon', 'tue', etc as the new `name` */
INSERT INTO yourtable (`companyId`, `name`, `open`, `close`)
SELECT `companyId`, 'mon', `open`, `close` FROM yourtable WHERE `name` = 'mon-fri'
INSERT INTO yourtable (`companyId`, `name`, `open`, `close`)
SELECT `companyId`, 'tue', `open`, `close` FROM yourtable WHERE `name` = 'mon-fri'
INSERT INTO yourtable (`companyId`, `name`, `open`, `close`)
SELECT `companyId`, 'wed', `open`, `close` FROM yourtable WHERE `name` = 'mon-fri'
INSERT INTO yourtable (`companyId`, `name`, `open`, `close`)
SELECT `companyId`, 'thur', `open`, `close` FROM yourtable WHERE `name` = 'mon-fri'
INSERT INTO yourtable (`companyId`, `name`, `open`, `close`)
SELECT `companyId`, 'fri', `open`, `close` FROM yourtable WHERE `name` = 'mon-fri'
/* Then delete the original mon-fri rows which you just expanded out */
DELETE FROM yourtable WHERE `name` = 'mon-fri'
http://sqlfiddle.com/#!2/cae33/1
(当然のことながら、この優れた提案は、一方的な編集によるAndriy Mの作業でした)
次のように、仮想テーブルを使用して、ステートメントの数とテーブル スキャンの数を減らすこともできます。
/* Cross-join the existing 'mon-fri' rows with a virtual table of day names
of 'mon' through 'fri' and insert the resulting set back into your table */
INSERT INTO yourtable (`companyId`, `name`, `open`, `close`)
SELECT t.`companyId`, v.`name`, t.`open`, t.`close`
FROM yourtable t
CROSS JOIN (
SELECT 'mon' AS `name` UNION ALL
SELECT 'tue' UNION ALL
SELECT 'wed' UNION ALL
SELECT 'thur' UNION ALL
SELECT 'fri'
) v
WHERE t.`name` = 'mon-fri';
/* Then delete the original mon-fri rows which you just expanded out */
DELETE FROM yourtable WHERE `name` = 'mon-fri';
http://sqlfiddle.com/#!2/98e35/1
コメント後の更新:
行を挿入するときにそれらの順序を強制することに実際の価値はありません。これは で行うのが最適SELECT
です。
それぞれを日単位で注文するにcompanyId
は、どの方法をとっても手間がかかります。LOWER(STR_TO_DATE())
withを呼び出して曜日の値を比較することもできますが、MySQL ではこのように省略されるため、to%a
を変更する必要もあります。その結果、一連の関数呼び出しが発生します。 thur
thu
代わりに、 で a を使用してCASE....
、次のORDER BY
ように序数値を各日に割り当てることができます。
ORDER BY
companyId,
CASE `name`
WHEN 'sun' THEN 1
WHEN 'mon' THEN 2
WHEN 'tue' THEN 3
WHEN 'wed' THEN 4
WHEN 'thur' THEN 5
WHEN 'fri' THEN 6
WHEN 'sat' THEN 7
ELSE 8 END
ただし、上記の方法はどちらもインデックス作成に適していません。
これをより効率的にする必要がある場合'mon','tue','wed'
は、最初に文字列などを保存するのではなく、関連する平日の値を保存することをお勧めします。詳細DAYOFWEEK()
については、を参照してください。