SQL语句拆分基于连接的表
-
21-09-2019 - |
题
我有由一个连接表信息链接到了只有少数条目表标签条主表。我想通过删除行或者创建拥有唯一我想要的条目的基础上,没有链接到某个标签的新表拆分物品表。有几百万篇文章。我怎样才能做到这一点?
不是所有的物品带任何标记,有的还有许多标签。
示例:
table Articles
primary_key id
table Info
foreign_key article_id
foreign_key tag_id
table Tags
primary_key id
这是很容易对我来说,隔离那些有比赛马上蝙蝠的文章,所以我想也许我能做到这一点,然后使用一个NOT IN语句,但就是这样运行缓慢,目前还不清楚它是否曾经打算完。我这样做,这些命令:
INSERT INTO matched_articles SELECT * FROM articles a LEFT JOIN info i ON a.id = i.article_id WHERE i.tag_id = 5;
INSERT INTO unmatched_articles SELECT * FROM articles a WHERE a.id NOT IN (SELECT m.id FROM matched_articles m);
如果它有差别,我对Postgres的。
解决方案
INSERT INTO matched_articles
SELECT * FROM articles a LEFT JOIN info i ON a.id = i.article_id WHERE i.tag_id = 5;
INSERT INTO unmatched_articles
SELECT * FROM articles a WHERE a.id NOT IN (SELECT m.id FROM matched_articles m);
有这么多错在这里,我不知道从哪里开始。事实上OK在你第一次插入你不需要左连接你实际上并没有一个。它应该是
INSERT INTO matched_articles
SELECT * FROM articles a INNER JOIN info i ON a.id = i.article_id WHERE i.tag_id = 5;
假如你需要一个左连接,你将不得不
INSERT INTO matched_articles
SELECT * FROM articles a LEFT JOIN info i ON a.id = i.article_id AND i.tag_id = 5;
当你把东西从左侧的右侧加入到where子句(比搜索为空值等),然后将其转换为内部连接becasue它必须满足这一条件,因此记录,唐”吨具有匹配在矿井右表中elimiated。
现在第二个语句也可以在左边的一个特例加盟做,虽然你有什么会工作。
INSERT INTO matched_articles
SELECT * FROM articles a
LEFT JOIN info i ON a.id = i.article_id AND i.tag_id = 5
WHERE i.tag_id is null
这会给你一切都是除了那些匹配的物品表中的信息表中的记录。
现在接下来的事情,你不应该在没有指定要插入的字段写入插入staments。也不应该你曾经写使用select *特别是如果你有一个联接的SELECT语句。这通常是邋遢,懒惰的编码,应该是固定的。如果有人更改了表中的一个而不是其他的结构?这种事情是不好的维护,并在选择statment与加盟,这是两次返回collumn的情况下(连接列),这是服务器和网络资源的浪费。这只是编码差是懒得注明您需要什么,你只需要什么。因此,走出去的习惯,不用于任何生产代码做一遍。
如果您当前stament太慢,你也可以用正确的索引修复它。被索引两个表ID字段? Onthe如果有文章millionas另一方面,它需要时间来插入。它往往是更好地做到这一点分批也许50000在同一时间(还少,如果这时间太长)。只是做插入INA循环,选择顶XXX记录,然后循环,直到计数影响该行是没有的。
其他提示
您查询一下,除了第一个行应该是一个内部联接,而不是一个左连接。如果你想别的试一下,考虑一下:
INSERT INTO matched_articles
SELECT *
FROM articles a
INNER JOIN info i ON a.id = i.article_id
WHERE i.tag_id = 5;
INSERT INTO unmatched_articles
SELECT *
FROM articles a
LEFT JOIN info i ON a.id = i.article_id AND a.id <> 5
WHERE a.id IS NULL
这可能会更快,但说真的,你有什么可能是确定的,如果你只需要做一次。
不确定,如果Postgres有一个临时表的概念。结果 下面是如何可以做到这一点,以及
CREATE Table #temp
AS SELECT A.ID, COUNT(i.*) AS Total
FROM Articles A
LEFT JOIN info i
ON A.id = i.Article_ID AND i.Tag_ID = 5
GROUP BY A.ID
INSERT INTO Matched_Articles
SELECT A.*
FROM Articles A INNER JOIN #temp t
ON A.ID = t.Article_ID AND T.Total = 0
DELETE FROM #Temp
WHERE Total = 0
INSERT INTO UnMatched_Articles
SELECT A.*
FROM Articles AINNER JOIN #temp t
ON A.ID = t.Article_ID
请注意,我没有使用任何编辑器来尝试了这一点。结果 我希望这给你提示我如何将接近这一点。