我有两张桌子:
MYTABLE1
UserId (int) (primary_key)
Save (blob)
mytable2
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
当两个表都有UserId = 25的用户时,这样就可以了,Save设置为''。但是,如果一个表没有UserId = 25的用户,但另一个表没有,那么Save就不会设置为''。这不是我想要的行为。
OR不是要使用的东西,因为其他保存将被设置为''没有UserId为25.所以我需要什么?
答案 0 :(得分:2)
您的查询使用旧式逗号语法进行连接操作。 (SQL中存在一些问题... dbSv1
用作限定符,但它不会显示为表名或表别名。我们假设应该是{{1} }。
您的查询相当于:
tb2
如果在 UPDATE mytable1 tb1
JOIN mytable2 tb2
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
AND tb2.userid=25
或tb1
中找不到匹配的行,则JOIN操作将生成一个空集。这是预期的行为。
考虑从此查询返回的结果集:
tb2
当tb2中没有满足谓词的行时,查询不会返回任何行。
您可以使用“外部”连接使其中一个表的返回行可选。例如,即使 SELECT tb1.userid
, tb2.userid
FROM mytable1 tb1
JOIN mytable2 tb2
WHERE tb1.userid=25
AND tb2.userid=25
...
mytable1
mytable2
如果 UPDATE mytable1 tb1
LEFT
JOIN mytable2 tb2
ON tb2.userid=25
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
中的行没有userid = 25,那么这将不会更新任何行。
MySQL不支持mytable1
。但你尝试这样的事情,使用内联视图返回一行,然后对mytable1和mytable2执行外连接......
FULL OUTER JOIN
SQLFiddle演示:http://sqlfiddle.com/#!9/6f8598/1
<强>后续强>
“join”是一种常见的SQL操作。你不应该在找到有关它的功能的信息方面遇到任何麻烦。
“+ 0”并非绝对必要。这是MySQL中CAST到数字的便捷简写。作为测试,看看MySQL为此返回的内容:
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 = ''
内联视图的目的是返回单行。我们可以编写查询来对user_id进行两次硬编码,并忽略从行视图返回的内容....
SELECT '25' + 0
, '25xyz' + 0
, 'abc' + 0
我的偏好是更清楚地表明我们的意图是使两个值相同。我们可以编写其中一个是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 = 25
LEFT
JOIN mytable t2
ON t2.user_id = 25
我们有点“失去”这两个价值相同的想法。为了获得仅指定一次的硬编码值,我让内联视图返回我们想要在外连接的ON子句中“匹配”的值。
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 = ?
现在我的意图更清楚......我正在寻找“一个”user_id值。添加“+ 0”表示无论传入什么值(例如'25','foo'或其他什么),我的声明都会将其解释为数值。
内联视图
我使用了“内联视图”这个术语。这只是我们通常有一个表的上下文中使用的SELECT查询。
e.g。如果我有一个名为 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
的表,我可以写一个查询...
mine
测试它并看到它返回行,yada,yada。
我也可以这样做:在parens中包装该查询并在另一个语句中引用它到位,就像这样......
SELECT m.id, m.name FROM mine m
MySQL要求我们为其分配一个别名,就像我们可以做的那样,如果它是一个表。我们将其称为内联视图,因为它类似于我们用于存储视图的模式。让我们来看看这样做的演示。
(这只是模式的一个示例;我们不想这样做的原因。)
SELECT t.*
FROM ( SELECT m.id, m.name FROM mine m ) t
然后我们可以这样做:
CREATE VIEW myview
AS
SELECT m.id, m.name FROM mine m
;
使用内嵌视图,我们遵循相同的模式,但我们绕过了单独的 SELECT t.* FROM myview t
语句。 (这是一个导致隐式提交和创建数据库对象的DDL语句。)绕过它,我们有效地创建了一个仅存在于语句上下文中的视图,并在语句中执行“内联”。 / p>
create view
MySQL文档将内联视图称为“派生表”。如果我们(意外地)忘记别名,我们得到的错误就说“每个派生表必须有一个别名”。用于除MySQL以外的数据库的更通用的术语是“内联视图”。