SQLite LEFT JOIN 计数(*)?
SQLite LEFT JOIN count(*)?
我需要连接两个表(好吧,实际上是两个视图),以便对于左视图的每个选定行,都有来自右视图的行数。这对我来说听起来像是一个 LEFT JOIN,但在 SQLite(这个测试 database)和一个 LEFT JOIN 查询中:
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, count(SECONDARY.label_id) NOlabels
FROM segment_extended TARGET LEFT JOIN segment_extended SECONDARY
WHERE TARGET.session_id = SECONDARY.session_id AND TARGET.lt_name= "Word" AND SECONDARY.lt_name ="Comments"
AND ((SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END) OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND TARGET.label != '' AND SECONDARY.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id;
我只得到了我期望的一小部分:
2 3 3 1
2 3 9 1
更扩展的查询给出了正确的结果:
SELECT session_id, labeltype_id, label_id, max(NOlabels) NOlabels
FROM (SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, count(SECONDARY.label_id) NOlabels
FROM segment_extended TARGET , segment_extended SECONDARY
WHERE TARGET.session_id = SECONDARY.session_id AND TARGET.lt_name= "Word" AND SECONDARY.lt_name ="Comments"
AND ((SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END) OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND TARGET.label != '' AND SECONDARY.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id
UNION
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, 0 NOlabels
FROM segment_extended TARGET
WHERE TARGET.lt_name= "Word"
AND TARGET.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id)
GROUP BY session_id, labeltype_id, label_id
ORDER BY session_id,labeltype_id, label_id
session_id labeltype_id label_id NOlabels
2 3 2 0
2 3 3 1
2 3 4 0
2 3 5 0
2 3 7 0
2 3 8 0
2 3 9 1
2 3 10 0
但它似乎不必要地复杂。我对左连接做错了什么?
您的连接不是左连接。
如果没有匹配连接条件的行,左连接会为右连接添加 NULL 值 table。
但是你的查询没有join条件,WHERE条件不受LEFT JOIN子句影响。
将 WHERE 替换为 ON。
进行左联接时,您必须将左联接中的空值计为 0 条记录,但仍包括它们。您可以在内部查询中使用 CASE 构造来完成此操作,然后在外部分组依据中使用 SUM 聚合函数。
SELECT session_id, labeltype_id, label_id, sum(has_label) NOlabels
FROM (
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, CASE WHEN SECONDARY.label_id is NULL then 0 else 1 END has_label
FROM
segment_extended TARGET
LEFT JOIN
segment_extended SECONDARY on
TARGET.session_id = SECONDARY.session_id
AND SECONDARY.lt_name ="Comments"
AND ((
SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END)
OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND SECONDARY.label != ''
WHERE TARGET.lt_name= "Word" AND TARGET.label != '')
GROUP BY session_id, labeltype_id, label_id
我需要连接两个表(好吧,实际上是两个视图),以便对于左视图的每个选定行,都有来自右视图的行数。这对我来说听起来像是一个 LEFT JOIN,但在 SQLite(这个测试 database)和一个 LEFT JOIN 查询中:
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, count(SECONDARY.label_id) NOlabels
FROM segment_extended TARGET LEFT JOIN segment_extended SECONDARY
WHERE TARGET.session_id = SECONDARY.session_id AND TARGET.lt_name= "Word" AND SECONDARY.lt_name ="Comments"
AND ((SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END) OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND TARGET.label != '' AND SECONDARY.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id;
我只得到了我期望的一小部分:
2 3 3 1
2 3 9 1
更扩展的查询给出了正确的结果:
SELECT session_id, labeltype_id, label_id, max(NOlabels) NOlabels
FROM (SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, count(SECONDARY.label_id) NOlabels
FROM segment_extended TARGET , segment_extended SECONDARY
WHERE TARGET.session_id = SECONDARY.session_id AND TARGET.lt_name= "Word" AND SECONDARY.lt_name ="Comments"
AND ((SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END) OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND TARGET.label != '' AND SECONDARY.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id
UNION
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, 0 NOlabels
FROM segment_extended TARGET
WHERE TARGET.lt_name= "Word"
AND TARGET.label != ''
GROUP BY TARGET.session_id,TARGET.labeltype_id, TARGET.label_id)
GROUP BY session_id, labeltype_id, label_id
ORDER BY session_id,labeltype_id, label_id
session_id labeltype_id label_id NOlabels
2 3 2 0
2 3 3 1
2 3 4 0
2 3 5 0
2 3 7 0
2 3 8 0
2 3 9 1
2 3 10 0
但它似乎不必要地复杂。我对左连接做错了什么?
您的连接不是左连接。
如果没有匹配连接条件的行,左连接会为右连接添加 NULL 值 table。 但是你的查询没有join条件,WHERE条件不受LEFT JOIN子句影响。
将 WHERE 替换为 ON。
进行左联接时,您必须将左联接中的空值计为 0 条记录,但仍包括它们。您可以在内部查询中使用 CASE 构造来完成此操作,然后在外部分组依据中使用 SUM 聚合函数。
SELECT session_id, labeltype_id, label_id, sum(has_label) NOlabels
FROM (
SELECT TARGET.session_id session_id, TARGET.labeltype_id labeltype_id, TARGET.label_id label_id, CASE WHEN SECONDARY.label_id is NULL then 0 else 1 END has_label
FROM
segment_extended TARGET
LEFT JOIN
segment_extended SECONDARY on
TARGET.session_id = SECONDARY.session_id
AND SECONDARY.lt_name ="Comments"
AND ((
SECONDARY.start <= TARGET.start AND TARGET.END <= SECONDARY.END)
OR (TARGET.start <= SECONDARY.start AND SECONDARY.END <= TARGET.END))
AND SECONDARY.label != ''
WHERE TARGET.lt_name= "Word" AND TARGET.label != '')
GROUP BY session_id, labeltype_id, label_id