Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql-基于其他行更新行_Sql_Mysql_Database - Fatal编程技术网

mysql-基于其他行更新行

mysql-基于其他行更新行,sql,mysql,database,Sql,Mysql,Database,我希望根据基于其他行的特定条件更新某些行。假设该表如下所示: COLUMNS: time type genre doubles triples ROW 1: 2010.06.21 12:00 1 1 0 0 ROW 2: 2010.06.21 12:00 1 2 0 0 ROW 3: 2010.06.21 12:00

我希望根据基于其他行的特定条件更新某些行。假设该表如下所示:

COLUMNS:   time              type     genre    doubles     triples
ROW 1:    2010.06.21 12:00    1        1        0            0
ROW 2:    2010.06.21 12:00    1        2        0            0
ROW 3:    2010.06.21 12:00    1        1        0            0
ROW 4:    2010.06.21 12:00    2        3        0            0
ROW 5:    2010.06.22 12:00    2        2        0            0
ROW 6:    2010.06.22 12:00    2        3        0            0
ROW 7:    2010.06.22 12:00    1        1        0            0
我希望根据以下规则更新doubles和triples列:

1仅查看更新行之间时间=时间且类型=类型的行,例如行1、2、3和行5和6

2下一步,计算这些行之间的不同类型,如果有两种不同类型,则将doubles列更改为1,如果有三种,则将triples列更改为1。例如,在上面的表格中,第1、2、3行的doubles=1,因为这三行之间有两种不同的类型。第5行和第6行的double=1,因为这两行之间又有两种不同的类型。双can=1和三can=1,但不能同时使用

现在,我可以很容易地根据这些规则编写一些PHP,但我想知道是否有一种方法可以在mysql中完成这一切?似乎我总是对SQL语句所能做的事情感到惊讶

可能类似于doubles和triples列的两个不同语句:

Doubles-更新myTable集合Doubles=1,其中时间=时间,类型=类型。。。但是,您如何解释上面的规则2,即计算具有唯一类型的行数

这在mysql中是可能的还是PHP就是正确的方法


提前感谢

可以使用sub-select和CASE表达式,或者通过将计数与列的计数进行比较,但由于MySQL不允许您选择sub-select中正在更新的表,这将很困难

你可以很容易地在一个select中完成,因为你没有指定它,所以我给了这个表一个“recordings”的名称;在SQL中提供示例而不是预先格式化的文本总是有帮助的:

SELECT r0.id, r0.`time`, r0.`type`, r0.`genre`,
     COUNT(DISTINCT r1.genre) = 2 AS doubles,
     COUNT(DISTINCT r1.genre) = 3 AS triples
  FROM recordings AS r0
    JOIN recordings AS r1 ON r0.`time`=r1.`time` AND r0.`type`=r1.`type`
  GROUP BY r0.`id`, r0.`time`, r0.`type`, r0.`genre`
然后,您可以将其用作或的基础:


如果组经常更改,则视图是更好的选择。它还确保了数据的可靠性。如果必须运行查询来更新double和triples列,则插入行后数据库通常会立即处于不一致状态,这可能会有所帮助,但与更新中的子选择一样,触发器在从正在更新的表中进行选择时会出现问题。视图和查询也更容易允许额外的列,例如比存储过程大四倍。

当然,您可以在一个查询中完成。使用此示例表:

create table duotri (time varchar(100), type int, genre int, doubles int, triples int);
insert duotri values
('2010.06.21 12:00'    ,1        ,1        ,0            ,0),
('2010.06.21 12:00'    ,1        ,2        ,0            ,0),
('2010.06.21 12:00'    ,1        ,1        ,0            ,0),
('2010.06.21 12:00'    ,2        ,3        ,0            ,0),
('2010.06.22 12:00'    ,2        ,2        ,0            ,0),
('2010.06.22 12:00'    ,2        ,3        ,0            ,0),
('2010.06.22 12:00'    ,1        ,1        ,0            ,0);
update语句应该连接到分组表单,以获得double和triple

update duotri t1
inner join (
    select time, type,
     case when count(distinct genre) = 2 then 1 else 0 end doubles,
     case when count(distinct genre) = 3 then 1 else 0 end triples
    from duotri
    group by time, type) t2
   on t1.time=t2.time and t1.type=t2.type
set t1.doubles=t2.doubles, t1.triples = t2.triples;

谢谢,我会玩一下,让你知道它是如何工作的
update duotri t1
inner join (
    select time, type,
     case when count(distinct genre) = 2 then 1 else 0 end doubles,
     case when count(distinct genre) = 3 then 1 else 0 end triples
    from duotri
    group by time, type) t2
   on t1.time=t2.time and t1.type=t2.type
set t1.doubles=t2.doubles, t1.triples = t2.triples;