mysql - 在mysql中用2行替换一行

标签 mysql sql

如何用 mysql 中具有相同数据的 5 行替换一行。例如,我有这个表

 id   |   companyId   |      name       |  open  |  close
 1    |    1          |    mon-fri      |  10:00 |  19:00  
 2    |    1          |      sat        |  10:00 |  12:00 
 3    |    1          |      sun        |  10:00 |  12:00 
 4    |    2          |    mon-fri      |  10:00 |  16:00  
 5    |    2          |      sat        |  10:00 |  13:00 
 6    |    2          |      sun        |  10:00 |  13:00 

我想将 mon-fri 的名称字段转换为 mon 、 tues 、 wed 、 thur 、 fri 。

 id   |   companyId   |      name       |  open  |  close
 1    |    1          |    mon     |  10:00 |  19:00  
 2    |    1          |    tues    |  10:00 |  19:00 
 3    |    1          |    wed     |  10:00 |  19:00 
 4    |    1          |    thur    |  10:00 |  19:00   
 5    |    1          |    fri     |  10:00 |  19:00  
 6    |    1          |    sat     |  10:00 |  12:00 
 7    |    1          |    sun     |  10:00 |  12:00 
.
.
.

最佳答案

您无法通过 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

评论后更新:

插入行时强制其顺序没有实际值(value),最好在 SELECT 中完成。

要按天为每个companyId订购,无论采用哪种方式都需要做一些工作。您可以使用 %a 调用 LOWER(STR_TO_DATE()) 并比较工作日值,但是您还需要将 thur 更改为 thu 因为这是 MySQL 的缩写方式。这会导致一堆函数调用。

相反,您可以在 ORDER BY 中使用 CASE.... 为每一天分配序数值,例如:

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'等,而是存储它们关联的工作日值(value)。请参阅DAYOFWEEK()了解详情。

关于mysql - 在mysql中用2行替换一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13895726/

相关文章:

PHP - Mysqli 错误

mysql - 使用 mysql 变量的问题

php - 如何使用php循环具有默认前缀的mysql表

SQL : counting and grouping by on the same column with conditions

sql - PostgreSQL:运行查询的行数 'by minute'

mysql - 子查询 - 记录不是有序的

mysql - 在mysql中创建 View 时可以将单元格设置为数组吗

mysql - "IN"子句的 SQL 对应项

mysql - 在 HQL 中使用 MySQL 将字符串转换为时间

php - 按频率对 SQL 查询记录排序