考虑以下三个MySQL表:
tweets urls tweets_urls
--------------------------- --------------------- ----------------
tweet_id text spam url_id host spam tweet_id url_id
--------------------------- --------------------- ----------------
1 I love cnn.com 0 16 cnn.com 0 1 16
2 fox.com is fuk 0 17 fox.com 1 2 17
3 love me! 0 4 16
4 blah cnn.com 0
5 nice fox.com 0
我想根据tweets_urls更新tweets.spam,这意味着查询的输出应该是
tweets
---------------------------
tweet_id text spam
---------------------------
1 I love cnn.com 0 <-- tweets_urls tells me tweet_id 1 has url_id 16
2 fox.com is fuk 1 in it, and the urls-table tells me that url 16
3 love me! 0 is not spam (spam = 0)
4 blah cnn.com 0
5 nice fox.com 1
我希望我能说清楚自己。我一直在摆弄它,现在有类似的东西。我知道它不正确,但不知道如何重新开始。你呢?
UPDATE tweets SET spam = (
SELECT spam FROM urls
LEFT JOIN tweets_urls
WHERE urls.url_id = tweets_urls.url_id
)
任何帮助将不胜感激: - )
答案 0 :(得分:3)
您忘记将子选择关联回tweets
表和联接中的ON
子句:
UPDATE tweets SET spam = (
SELECT spam FROM urls
LEFT JOIN tweets_urls ON urls.url_id = tweets_urls.url_id
WHERE tweets_urls.tweet_id = tweets.tweet_id
)
在以下情况下,您还没有定义要执行的操作:
tweets_urls
中没有针对tweet_id tweets_urls
中有多个条目用于tweet_id 最后,作为旁注,你确定你想要像这样更新吗?这听起来更像是你想要使用视图或存储过程生成的东西 - 除非urls
和tweets_urls
只是你现在添加的表,以帮助填充tweets
表然后会丢弃后面。
答案 1 :(得分:1)
对于您的给定数据,此查询返回结果集...
SELECT t.tweet_id
, t.text
, IFNULL(s.spam,t.spam) AS spam
FROM tweets t
LEFT
JOIN ( SELECT tu.tweet_id, MAX(u.spam) AS spam
FROM tweets_urls tu
JOIN urls u ON u.url_id = tu.url_id
WHERE u.spam = 1
GROUP BY tu.tweet_id
) s
ON s.tweet_id = t.tweet_id
但是对于给定的tweet_id,或者当没有匹配的url等时,我们已经对tweets_url中的多行应该做什么做了一些假设。
如果您想要的是将推文标记为 “spam = 1”,只要发现该推文与任何标记为“spam = 1”的网址相关,否则,该推文应标记为“spam = 0”......
这将根据该规则为推文中的每一行设置垃圾邮件列......
UPDATE tweets t
LEFT
JOIN ( SELECT tu.tweet_id, MAX(u.spam) AS spam
FROM tweets_urls tu
JOIN urls u ON u.url_id = tu.url_id
WHERE u.spam = 1
GROUP BY tu.tweet_id
) s
ON s.tweet_id = t.tweet_id
SET t.spam = IFNULL(s.spam,0)
如果您想单独留下垃圾邮件列(将其设置为设置的任何内容),并且只想更新当前值设置为0的行,并且应该设置为1,根据“匹配” url有spam = 1“,你可以这样做:
UPDATE tweets t
JOIN ( SELECT tu.tweet_id
FROM tweets_urls tu
JOIN urls u ON u.url_id = tu.url_id
WHERE u.spam = 1
GROUP BY tu.tweet_id
) s
ON s.tweet_id = t.tweet_id
SET t.spam = 1
WHERE t.spam = 0
请注意tweets表上的谓词,我们只会更新当前设置为零的垃圾邮件的行。请注意,我们不需要从urls表中引用垃圾邮件列的值,我们已经测试它等于1,所以我们可以在tweets.spam的值赋值中使用文字1柱。另请注意,我们正在进行INNER JOIN(而不是LEFT OUTER JOIN),因此,我们只会更新将被赋值为1的行。