在 MySQL 中用 EXISTS 查询的两个条件
Two conditions for query in MySQL with EXISTS
我正在尝试获取满足 EXISTS 条件的两个条件的作者。但是,当子查询实际工作时,我一直在获取 author table 中的所有条目。
谁能告诉我我的查询到底出了什么问题?我正在统计条目数。
SELECT COUNT(*)
FROM author
WHERE
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%'
GROUP BY A.author_id
HAVING COUNT(*)>=10)
AND
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/sigmod/%'
GROUP BY A.author_id
HAVING COUNT(*)>=10)
;
尝试:
SELECT COUNT(A.author_id)
FROM
author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE
P.pub_key LIKE '%/pvldb/%' OR P.pub_key LIKE '%/sigmod/%'
GROUP BY A.author_id
HAVING COUNT(A.author_id) >= 10;
您只需要将子查询关联到主查询即可:
SELECT COUNT(*)
FROM author as AA
WHERE
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%'
AND AA.author_id=A.author_id
GROUP BY A.author_id
HAVING COUNT(*)>=10)
AND
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/sigmod/%'
AND AA.author_id=A.author_id
GROUP BY A.author_id
HAVING COUNT(*)>=10)
;
您的子查询与您的主查询没有任何关系。因此,对于每条记录,您都会问同样的问题:"Does an author with at least ten publications of a certain type exist in the table?"。每条记录的答案都相同,因此您可以取回所有记录。你真正想问的是:"Do at least ten publications of a certain type exist for this author in the table?"
SELECT COUNT(*)
FROM author
WHERE EXISTS
(
SELECT 1
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE AP.author_id = author.author_id
AND P.pub_key LIKE '%/pvldb/%'
GROUP BY AP.author_id
HAVING COUNT(*) >= 10
)
AND EXISTS
(
SELECT 1
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE AP.author_id = author.author_id
AND P.pub_key LIKE '%/sigmod/%'
GROUP BY AP.author_id
HAVING COUNT(*) >= 10
);
如果要编写非相关子查询,请改用IN
:
SELECT COUNT(*)
FROM author
WHERE author_id IN
(
SELECT AP.author_id
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%'
GROUP BY AP.author_id
HAVING COUNT(*) >= 10
)
AND author_id IN
(
SELECT AP.author_id
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/sigmod/%'
GROUP BY A.author_id
HAVING COUNT(*) >= 10
);
下面是如何使用单个子查询执行此操作:
SELECT COUNT(*)
FROM
(
SELECT AP.author_id
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%' OR P.pub_key LIKE '%/sigmod/%'
GROUP BY AP.author_id
HAVING COUNT(CASE WHEN P.pub_key LIKE '%/pvldb/%' THEN 1 END) >= 10
AND COUNT(CASE WHEN P.pub_key LIKE '%/sigmod/%' THEN 1 END) >= 10
) found_authors;
我正在尝试获取满足 EXISTS 条件的两个条件的作者。但是,当子查询实际工作时,我一直在获取 author table 中的所有条目。 谁能告诉我我的查询到底出了什么问题?我正在统计条目数。
SELECT COUNT(*)
FROM author
WHERE
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%'
GROUP BY A.author_id
HAVING COUNT(*)>=10)
AND
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/sigmod/%'
GROUP BY A.author_id
HAVING COUNT(*)>=10)
;
尝试:
SELECT COUNT(A.author_id)
FROM
author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE
P.pub_key LIKE '%/pvldb/%' OR P.pub_key LIKE '%/sigmod/%'
GROUP BY A.author_id
HAVING COUNT(A.author_id) >= 10;
您只需要将子查询关联到主查询即可:
SELECT COUNT(*)
FROM author as AA
WHERE
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%'
AND AA.author_id=A.author_id
GROUP BY A.author_id
HAVING COUNT(*)>=10)
AND
EXISTS (SELECT A.author_id, A.author_name
FROM author AS A
INNER JOIN author_publication AS AP ON A.author_id = AP.author_id
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/sigmod/%'
AND AA.author_id=A.author_id
GROUP BY A.author_id
HAVING COUNT(*)>=10)
;
您的子查询与您的主查询没有任何关系。因此,对于每条记录,您都会问同样的问题:"Does an author with at least ten publications of a certain type exist in the table?"。每条记录的答案都相同,因此您可以取回所有记录。你真正想问的是:"Do at least ten publications of a certain type exist for this author in the table?"
SELECT COUNT(*)
FROM author
WHERE EXISTS
(
SELECT 1
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE AP.author_id = author.author_id
AND P.pub_key LIKE '%/pvldb/%'
GROUP BY AP.author_id
HAVING COUNT(*) >= 10
)
AND EXISTS
(
SELECT 1
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE AP.author_id = author.author_id
AND P.pub_key LIKE '%/sigmod/%'
GROUP BY AP.author_id
HAVING COUNT(*) >= 10
);
如果要编写非相关子查询,请改用IN
:
SELECT COUNT(*)
FROM author
WHERE author_id IN
(
SELECT AP.author_id
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%'
GROUP BY AP.author_id
HAVING COUNT(*) >= 10
)
AND author_id IN
(
SELECT AP.author_id
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/sigmod/%'
GROUP BY A.author_id
HAVING COUNT(*) >= 10
);
下面是如何使用单个子查询执行此操作:
SELECT COUNT(*)
FROM
(
SELECT AP.author_id
FROM author_publication AS AP
INNER JOIN publication AS P ON AP.pub_id = P.pub_id
WHERE P.pub_key LIKE '%/pvldb/%' OR P.pub_key LIKE '%/sigmod/%'
GROUP BY AP.author_id
HAVING COUNT(CASE WHEN P.pub_key LIKE '%/pvldb/%' THEN 1 END) >= 10
AND COUNT(CASE WHEN P.pub_key LIKE '%/sigmod/%' THEN 1 END) >= 10
) found_authors;