首页 > 解决方案 > 如何有效地检索同一张表中的相交值?

问题描述

假设我有下表“some_table”,它看起来像这样,

email | friend_email |
----------------------
s1    | f1           |
----------------------
s2    | f1           |
----------------------
s1    | f2           |
----------------------
s2    | f2           |
----------------------
s3    | f2           |
----------------------
s1    | f3           |
----------------------
s2    | f3           |
----------------------
s4    | f3           |

然后,我想在 f1、f2 和 f3 之间的“电子邮件”下找到不同的和共同的值。返回的结果应该只有 s1 和 s2。

使用的 SQL 语句将如下所示,

SELECT DISTINCT email FROM some_table WHERE friend_email IN ('f1') AND email in (SELECT DISTINCT email FROM some_table WHERE friend_email IN ('f2')) AND email in (SELECT DISTINCT email FROM some_table WHERE friend_email IN ('f3'));

问题是当我有更多的朋友电子邮件要添加时,它会变得很长。

在我的 node.js 代码中,我想使用“?” (我认为它们被称为常量?)在 sql 语句中,但我没有成功。代码示例如下,

var getCommonFriends = "SELECT DISTINCT email FROM some_table WHERE friend_email = '?'";
var getCommonFriendsAppend = " AND email in (SELECT DISTINCT email FROM some_table WHERE friend_email = '?')";

var friends = ["f1", "f2", "f3"];

var combinedSqlStatement = getCommonFriends;
var totalFriends = friends.length;
for(var i = 0; i < totalFriends; i++){
    combinedSqlStatement = combinedSqlStatement + getCommonFriendsAppend;
}

我的问题是我如何想出一个执行上述操作并使用常量又名“?”的 sql 语句。

标签: mysqlnode.js

解决方案


我想你也许可以在这里做一个简单的聚合查询:

SELECT email
FROM some_table
WHERE friend_email IN ('f1', 'f2', 'f3')
GROUP BY email
HAVING COUNT(DISTINCT friend_email) = 3;

此选项按电子邮件项目聚合,然后断言某组朋友都存在/与该项目相关联。这个解决方案的扩展性很好,因为要扩展到更多的朋友,您只需要在IN子句中添加另一个朋友,并在查询结束时更改不同的计数断言。

演示

这是一个在 Node JS 中可能更友好的查询版本:

SELECT email
FROM some_table
WHERE friend_email IN
(
    SELECT ? FROM dual UNION ALL
    SELECT ? FROM dual UNION ALL
    SELECT ? FROM dual
)
GROUP BY email
HAVING COUNT(DISTINCT friend_email) = 3;

然后,将文字值'f1''f2'和绑定'f3'到上述查询。

演示


推荐阅读