我有两个表:
SELECT * FROM data;
+----+---+---+
| id | c | g |
+----+---+---+
| 1 | 1 | 2 |
| 2 | 1 | 2 |
| 3 | 1 | 2 |
| 4 | 1 | 3 |
| 5 | 2 | 2 |
| 6 | 2 | 3 |
| 7 | 2 | 3 |
+----+---+---+
和
SELECT * FROM changes;
+----+-------+-------+---+
| id | c_old | c_new | g |
+----+-------+-------+---+
| 1 | 1 | 2 | 2 |
| 2 | 2 | 1 | 3 |
| 3 | 1 | 2 | 2 |
+----+-------+-------+---+
对于其中的每一行,changes
我都需要在data
where中精确地更改一行data.g=changes.g and data.c=changes.c_old
。(假设总会有足够的匹配项)
我正在尝试通过以下查询执行此操作:
UPDATE
data INNER JOIN changes ON
data.c=changes.c_old AND p.g=changes.g
SET data.c_id=changes.c_new
WHERE data.id IN(
SELECT id FROM (
SELECT data.id from
data INNER JOIN changes ON
data.c=changes.c_old AND data.g=changes.g
GROUP BY changes.id
) AS another_table
)
现在,令我感到惊讶的是,一团糟的查询运行了。但是,它不能满足我的需求。最里面的选择返回此表:
+----+
| id |
+----+
| 1 |
| 6 |
| 1 |
+----+
注意1
出现两次。这意味着当我需要更改三行时,只有两行被更改(或行1被更改了两次)。有没有办法确保该子查询中的每个ID都是唯一的?有没有更好的办法来解决这个问题?
提前致谢!
您选择的字段不属于该组,也不属于该组。
SELECT data.id from
data INNER JOIN changes ON
data.c=changes.c_old AND data.g=changes.g
GROUP BY changes.id
您应该在select的data.id上使用聚合函数,或将data.id添加到groupby(尽管我怀疑那也不是您想要的结果)
INNER JOIN是此数据集中的结果
+---------+--------+--------+------------+---------------+---------------+-----------+
| data.id | data.c | data.g | changes.id | changes.c_old | changes.c_new | changes.g |
+---------+--------+--------+------------+---------------+---------------+-----------+
| 1 | 1 | 2 | 1 | 1 | 2 | 2 |
| 1 | 1 | 2 | 3 | 1 | 2 | 2 |
| 2 | 1 | 2 | 1 | 1 | 2 | 2 |
| 2 | 1 | 2 | 3 | 1 | 2 | 2 |
| 3 | 1 | 2 | 1 | 1 | 2 | 2 |
| 3 | 1 | 2 | 3 | 1 | 2 | 2 |
| 6 | 2 | 3 | 2 | 2 | 1 | 3 |
| 7 | 2 | 3 | 2 | 2 | 1 | 3 |
+---------+--------+--------+------------+---------------+---------------+-----------+
由于连接中有多个匹配项,因此将1,2,3展开,而由于没有匹配项而将4,5删除了
然后,您将按changes.id分组,这将导致(分组后在CSV列表中显示值)
+---------+--------+--------+------------+---------------+---------------+-----------+
| data.id | data.c | data.g | changes.id | changes.c_old | changes.c_new | changes.g |
+---------+--------+--------+------------+---------------+---------------+-----------+
| 1,2,3 | 1,1,1 | 2,2,2 | 1 | 1,1,1 | 2,2,2 | 2,2,2 |
| 1,2,3 | 1,1,1 | 2,2,2 | 3 | 1,1,1 | 2,2,2 | 2,2,2 |
| 6,7 | 2,2 | 3,3 | 2 | 2,2 | 1,1 | 3,3 |
+---------+--------+--------+------------+---------------+---------------+-----------+
由于没有从可用选项中选择值的合计或确定性方式,因此将从为changes.id 1和3选择的data.id中获取1。
根据您想要的内容,您是否需要3行?所有不同的价值?您应该将确定性行为添加到选择中。
顺便说一句,我很确定其他SQL引擎将不允许该选择(例如MSSQL),因为它含糊不清。至于在这种情况下的MySQL行为,我相信它会从存储的第一行中选择第一个值,因此为什么在两种情况下都可能获得1,但可以自由选择所需的任何值。
http://dev.mysql.com/doc/refman/5.7/en/group-by-extensions.html
MySQL扩展了GROUP BY的使用,以便选择列表可以引用未在GROUP BY子句中命名的非聚合列。这意味着前面的查询在MySQL中是合法的。您可以使用此功能来避免不必要的列排序和分组,从而获得更好的性能。但是,这主要在每个组的每个未聚合列中未在GROUP BY中命名的所有值都相同时才有用。服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的。此外,通过添加ORDER BY子句不能影响从每个组中选择值。选择值之后,将对结果集进行排序,并且ORDER BY不会影响服务器在每个组中选择哪个值。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句