我有两个SQL查询,其中首先使用内部联接根据条件进行匹配,而另一个不使用。最终,我想要每个查询创建的列之间的区别。我怎样才能做到这一点?
我已经尝试像在一些类似的帖子中那样合并和加入查询,但这是行不通的。我想知道问题是否在每个查询中的联接周围。
查询1:
SELECT A.date, COUNT(DISTINCT A.id)
FROM A
INNER JOIN B
ON A.id = B.id AND A.date = B.date
AND B.col1 = 'value1'
LEFT JOIN C on C.key = A.key
WHERE A.col1 = 'value2'
AND C.category = 'cat1'
GROUP BY 1
ORDER BY 1 DESC
查询2:
SELECT A.date, COUNT(DISTINCT A.id)
FROM A
LEFT JOIN C on C.key = A.key
WHERE A.col1 = 'value2'
AND C.category = 'cat1'
GROUP BY 1
ORDER BY 1 DESC
答案 0 :(得分:1)
SELECT A.date, COUNT(DISTINCT A.id)
FROM A
INNER JOIN B
ON A.id = B.id AND A.date = B.date
AND B.col1 = 'value1'
LEFT JOIN C on C.key = A.key
WHERE A.col1 = 'value2'
AND C.category = 'cat1'
GROUP BY 1
ORDER BY 1 DESC
UNION
SELECT A.date, COUNT(DISTINCT A.id)
FROM A
LEFT JOIN C on C.key = A.key
WHERE A.col1 = 'value2'
AND C.category = 'cat1'
GROUP BY 1
ORDER BY 1 DESC
答案 1 :(得分:1)
一种简单的方法是使用JOIN
列对两个查询进行date
:
SELECT x.date, x.cnt, y.cnt, y.cnt - x.cnt
FROM
(
SELECT A.date, COUNT(DISTINCT A.id) AS cnt
FROM A
INNER JOIN B ON A.id = B.id AND A.date = B.date AND B.col1 = 'value1'
LEFT JOIN C on C.key = A.key
WHERE A.col1 = 'value2' AND C.category = 'cat1'
GROUP BY 1
) AS x
INNER JOIN (
SELECT A.date, COUNT(DISTINCT A.id) AS cnt
FROM A
LEFT JOIN C on C.key = A.key
WHERE A.col1 = 'value2' AND C.category = 'cat1'
GROUP BY 1
) AS y ON x.date = y.date
ORDER BY 1 DESC
您可能要根据数据布局调整联接类型:
LEFT JOIN
,如果所有日期都在第一个子查询中可用,但在第二个子查询中可能缺少RIGHT JOIN
(如果情况相反)FULL OUTER JOIN
,如果您希望两端都有可用的日期如果您选择以上任一选项,则当其中一项为COALESCE
时,需要使用NULL
来防止减法返回NULL
。
答案 2 :(得分:1)
您的c
的左联接实际上变成了内部联接,因为它用在NULL
子句中的WHERE
排除表达式中。因此,您可以直接内部联接c
和左联接b
。然后,您可以在一个count()
中使用一个个案,以仅计算来自b
的行被联接的实例。从另一个count()
中减去该值,然后计算所有出现的次数以获得差值。
SELECT a.date,
count(DISTINCT a.id)
-
count(DISTINCT CASE
WHEN b.id IS NOT NULL THEN
a.id
END)
FROM a
INNER JOIN c
ON c.key = a.key
AND c.category = 'cat1'
LEFT JOIN b
ON a.id = b.id
AND a.date = b.date
AND b.col1 = 'value1'
WHERE a.col1 = 'value2'
GROUP BY 1
ORDER BY 1 DESC;