MySql - 多表 - AND 不是正确的选择,但什么是?
MySql - Multitable - AND is not the correct choice, but what is?
我有两个 table:
我的table1
UserId (int) (primary_key)
Save (blob)
我的table2
UserId (int) (primary_key)
Save (blob)
我执行以下 mysql 命令:
UPDATE mytable1 tb1, mytable2 tb2 SET tb1.Save='', tb2 .Save='' WHERE tb1.UserId=25 AND dbSv1.UserId=25
当两个 table 都有一个 UserId = 25 的用户时,这会起作用并且保存设置为“”。但是,如果一个 table 没有 UserId = 25 的用户,而另一个有,则 Save 不会在有的用户中设置为 ''。这不是我想要的行为。
OR 不是要使用的东西,因为其他保存将设置为 '',其 UserId 不为 25。那么我需要什么?
您的查询使用老式逗号语法进行连接操作。 (SQL 中存在一些问题...... dbSv1
用作限定符,但它不会显示为 table 名称或 table 别名。我们假设应该是 tb2
.
您的查询等同于:
UPDATE mytable1 tb1
JOIN mytable2 tb2
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
AND tb2.userid=25
如果在 tb1
或 tb2
中都没有找到匹配的行,则 JOIN 操作将生成一个空集。这是预期的行为。
考虑从这个查询 return 编辑的结果集:
SELECT tb1.userid
, tb2.userid
FROM mytable1 tb1
JOIN mytable2 tb2
WHERE tb1.userid=25
AND tb2.userid=25
当 tb2 中没有满足谓词的行时,查询将不会 return 任何行。
您可以使用 "outer" 联接使来自 table 之一的 returning 行成为可选行。例如,即使 mytable2
...
中不存在匹配的行,也要更新 mytable1
UPDATE mytable1 tb1
LEFT
JOIN mytable2 tb2
ON tb2.userid=25
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
如果 mytable1
中没有 userid=25 的行,则不会更新任何行。
MySQL 不支持 FULL OUTER JOIN
。但是你尝试这样的事情,使用内联视图 return 一行,然后对 mytable1 和 mytable2...
执行外连接
UPDATE ( SELECT 25 + 0 AS userid ) i
LEFT
JOIN mytable1 tb1
ON tb1.userid = i.userid
LEFT
JOIN mytable2 tb2
ON tb2.userid = i.userid
SET tb1.save = ''
, tb2.save = ''
SQL小提琴演示:http://sqlfiddle.com/#!9/6f8598/1
跟进
一个"join"是一个普通的SQL操作。您应该可以轻松找到有关它的功能的信息。
“+ 0”并非绝对必要。 MySQL 中的 shorthand 转换为数字很方便。作为测试,请查看 MySQL return 的内容:
SELECT '25' + 0
, '25xyz' + 0
, 'abc' + 0
内联视图的目的是 return 单行。我们本可以编写查询以对 user_id 进行两次硬编码,并忽略从行视图中编辑的 return ....
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT 'foo' AS dontcare ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = 25
LEFT
JOIN mytable t2
ON t2.user_id = 25
我的偏好是更清楚地表明我们的意图是使两个值相同。我们可以编写代码,其中一个是 23,另一个是 27。这样做在语法上是有效的。当我们将其转换为带有绑定占位符的准备语句时...
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT 'foo' AS dontcare ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = ?
LEFT
JOIN mytable t2
ON t2.user_id = ?
我们有点 "lose" 这两个值相同的想法。为了只指定一次硬编码值,我有内联视图 return 我们想要在外部连接的 ON 子句中 "match" 的值。
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT ? AS user_id ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = i.user_id
LEFT
JOIN mytable t2
ON t2.user_id = i.user_id
现在我的意图更明确了...我正在寻找 "one" user_id 值。添加“+ 0”表示无论传入什么值(例如“25”、'foo' 或其他),我的语句都会将其解释为数值。
内联视图
我用了 "inline view" 这个词。这只是在我们通常有 table 的上下文中使用的 SELECT 查询。
例如如果我有一个名为 mine
的 table,我可以编写一个查询...
SELECT m.id, m.name FROM mine m
对其进行测试并查看它 return 行,yada,yada。
我也可以这样做:将该查询包装在括号中并在另一个语句中 代替 table 的 引用它,就像这样...
SELECT t.*
FROM ( SELECT m.id, m.name FROM mine m ) t
MySQL 要求我们为其分配一个别名,就像我们可以为 table 做的那样。我们称其为 内联视图 ,因为它类似于我们用于 存储视图 的模式。让我们看一下这样做的演示。
(这只是该模式的演示;出于某些原因我们不想这样做。)
CREATE VIEW myview
AS
SELECT m.id, m.name FROM mine m
;
那么我们可以这样做:
SELECT t.* FROM myview t
使用 内联视图 我们遵循相同的模式,但我们绕过了单独的 create view
语句。 (这是一个导致隐式提交并创建数据库对象的 DDL 语句。)绕过它,我们有效地创建了一个仅存在于语句上下文中的视图,并在语句中执行 "inline" .
SELECT t.* FROM ( SELECT m.id, m.name FROM mine m ) t
MySQL 文档将内联视图称为 "derived table"。如果我们(不小心)忘记了别名,我们返回的错误会显示类似 "every derived table must have a alias" 的内容。用于 MySQL 以外的数据库的更通用的术语是 "inline view"。
我有两个 table:
我的table1
UserId (int) (primary_key)
Save (blob)
我的table2
UserId (int) (primary_key)
Save (blob)
我执行以下 mysql 命令:
UPDATE mytable1 tb1, mytable2 tb2 SET tb1.Save='', tb2 .Save='' WHERE tb1.UserId=25 AND dbSv1.UserId=25
当两个 table 都有一个 UserId = 25 的用户时,这会起作用并且保存设置为“”。但是,如果一个 table 没有 UserId = 25 的用户,而另一个有,则 Save 不会在有的用户中设置为 ''。这不是我想要的行为。
OR 不是要使用的东西,因为其他保存将设置为 '',其 UserId 不为 25。那么我需要什么?
您的查询使用老式逗号语法进行连接操作。 (SQL 中存在一些问题...... dbSv1
用作限定符,但它不会显示为 table 名称或 table 别名。我们假设应该是 tb2
.
您的查询等同于:
UPDATE mytable1 tb1
JOIN mytable2 tb2
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
AND tb2.userid=25
如果在 tb1
或 tb2
中都没有找到匹配的行,则 JOIN 操作将生成一个空集。这是预期的行为。
考虑从这个查询 return 编辑的结果集:
SELECT tb1.userid
, tb2.userid
FROM mytable1 tb1
JOIN mytable2 tb2
WHERE tb1.userid=25
AND tb2.userid=25
当 tb2 中没有满足谓词的行时,查询将不会 return 任何行。
您可以使用 "outer" 联接使来自 table 之一的 returning 行成为可选行。例如,即使 mytable2
...
mytable1
UPDATE mytable1 tb1
LEFT
JOIN mytable2 tb2
ON tb2.userid=25
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
如果 mytable1
中没有 userid=25 的行,则不会更新任何行。
MySQL 不支持 FULL OUTER JOIN
。但是你尝试这样的事情,使用内联视图 return 一行,然后对 mytable1 和 mytable2...
UPDATE ( SELECT 25 + 0 AS userid ) i
LEFT
JOIN mytable1 tb1
ON tb1.userid = i.userid
LEFT
JOIN mytable2 tb2
ON tb2.userid = i.userid
SET tb1.save = ''
, tb2.save = ''
SQL小提琴演示:http://sqlfiddle.com/#!9/6f8598/1
跟进
一个"join"是一个普通的SQL操作。您应该可以轻松找到有关它的功能的信息。
“+ 0”并非绝对必要。 MySQL 中的 shorthand 转换为数字很方便。作为测试,请查看 MySQL return 的内容:
SELECT '25' + 0
, '25xyz' + 0
, 'abc' + 0
内联视图的目的是 return 单行。我们本可以编写查询以对 user_id 进行两次硬编码,并忽略从行视图中编辑的 return ....
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT 'foo' AS dontcare ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = 25
LEFT
JOIN mytable t2
ON t2.user_id = 25
我的偏好是更清楚地表明我们的意图是使两个值相同。我们可以编写代码,其中一个是 23,另一个是 27。这样做在语法上是有效的。当我们将其转换为带有绑定占位符的准备语句时...
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT 'foo' AS dontcare ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = ?
LEFT
JOIN mytable t2
ON t2.user_id = ?
我们有点 "lose" 这两个值相同的想法。为了只指定一次硬编码值,我有内联视图 return 我们想要在外部连接的 ON 子句中 "match" 的值。
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT ? AS user_id ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = i.user_id
LEFT
JOIN mytable t2
ON t2.user_id = i.user_id
现在我的意图更明确了...我正在寻找 "one" user_id 值。添加“+ 0”表示无论传入什么值(例如“25”、'foo' 或其他),我的语句都会将其解释为数值。
内联视图
我用了 "inline view" 这个词。这只是在我们通常有 table 的上下文中使用的 SELECT 查询。
例如如果我有一个名为 mine
的 table,我可以编写一个查询...
SELECT m.id, m.name FROM mine m
对其进行测试并查看它 return 行,yada,yada。
我也可以这样做:将该查询包装在括号中并在另一个语句中 代替 table 的 引用它,就像这样...
SELECT t.*
FROM ( SELECT m.id, m.name FROM mine m ) t
MySQL 要求我们为其分配一个别名,就像我们可以为 table 做的那样。我们称其为 内联视图 ,因为它类似于我们用于 存储视图 的模式。让我们看一下这样做的演示。
(这只是该模式的演示;出于某些原因我们不想这样做。)
CREATE VIEW myview
AS
SELECT m.id, m.name FROM mine m
;
那么我们可以这样做:
SELECT t.* FROM myview t
使用 内联视图 我们遵循相同的模式,但我们绕过了单独的 create view
语句。 (这是一个导致隐式提交并创建数据库对象的 DDL 语句。)绕过它,我们有效地创建了一个仅存在于语句上下文中的视图,并在语句中执行 "inline" .
SELECT t.* FROM ( SELECT m.id, m.name FROM mine m ) t
MySQL 文档将内联视图称为 "derived table"。如果我们(不小心)忘记了别名,我们返回的错误会显示类似 "every derived table must have a alias" 的内容。用于 MySQL 以外的数据库的更通用的术语是 "inline view"。