SQL - 选择具有最匹配列的行

标签 sql sqlite jdbc

我是数据库和 SQL 新手,三天以来一直在尝试解决这个问题。我有一个 Java 应用程序,它使用 JDBC 查询 SQLite 数据库。到目前为止,这工作得很好。但我无法弄清楚检索所需行所需的 SQL 查询。该表如下所示:

rowid | application | dstIP          | dstPort | value_to_return
      |             |                |         | 
0     | NULL        | NULL           | NULL    | 26
1     | NULL        | NULL           | 80      | 1
2     | NULL        | 192.168.178.31 | NULL    | 2
3     | NULL        | 192.168.178.31 | 80      | 3
4     | firefox     | NULL           | NULL    | 4
5     | firefox     | NULL           | 80      | 5
6     | firefox     | 192.168.178.31 | NULL    | 6 
7     | firefox     | 192.168.178.31 | 80      | 7

我的目标是获取大多数列匹配的行,如果没有列匹配,则应选择行 0。 这里有一些例子:

input                     -> row

firefox 192.168.178.31 80 -> 7
chrome  192.168.178.31 81 -> 2
chrome  192.168.178.30 82 -> 0
someapp 192.168.178.29 80 -> 1

到目前为止我最好的猜测是这个查询

SELECT * FROM table WHERE (application IS ? OR application IS NULL)
                      AND (dstIP IS  ? OR dstIP IS NULL)
                      AND (dstPort IS ? OR dstPort IS NULL)
                      ORDER BY application;

? 被替换为相应的输入值。如果不匹配,此查询将返回第 0 行。但如果有多个匹配项,它当​​然会返回几行。
我可以在 Java 应用程序中选择我需要的行,但我希望数据库能够为我工作。
如果存储过程是解决此问题的更好选择,我可以更改数据库,因为 SQLite 不支持它。

我希望我对问题的描述足够准确。任何帮助将不胜感激。

最佳答案

这应该可以解决问题:

SELECT * FROM (
    SELECT *, CASE application WHEN ? THEN 1 WHEN NULL THEN 0 ELSE NULL END
            + CASE dstIP WHEN ? THEN 1 WHEN NULL THEN 0 ELSE NULL END
            + CASE dstPort WHEN ? THEN 1 WHEN NULL THEN 0 ELSE NULL END AS Matches
    FROM table WHERE Matches IS NOT NULL
) GROUP BY application, dstIP, dstPort ORDER BY Matches DESC;

Matches 列将计算所有匹配的列,如果不匹配,则为 NULL

GROUP BY 没有聚合函数将捕获第一行(我希望!),这是最大匹配,因为内部查询按降序排序。

编辑:新版本:

SELECT *, CASE WHEN application IS ? THEN 1 WHEN application IS NULL THEN 0 ELSE NULL END
        + CASE WHEN dstIP IS ? THEN 1 WHEN dstIP IS NULL THEN 0 ELSE NULL END
        + CASE WHEN dstPort IS ? THEN 1 WHEN dstPort IS NULL THEN 0 ELSE NULL END AS Matches
FROM t
WHERE Matches IS NOT NULL
ORDER BY Matches DESC
LIMIT 1;

优点:您也可以比较NULL。缺点:当找到同等排名的比赛时,仅显示 1 场比赛。

关于SQL - 选择具有最匹配列的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19562212/

相关文章:

mysql - 如何在非常大的数据库上快速搜索

MySQL Group by week number a/multiple date 列

java - 应用程序已停止 android 模拟器 genymotion

python - 在 Windows 8 中从 .sql 文件创建 sqlite3 数据库

java - 为什么调用 Statement.close() 不会立即释放 Statement 对象创建的 ResultSet 对象?

sql - 为什么我的 SQL Server 2008 查询一直在运行?

php - 使用 C++ 将值添加到列中的现有 SQL 值

java - 在Java中的静态方法中创建SQLite连接

java - "Invalid method name: ' 在 Java 中使用 Hive Client 执行 '"错误

java - java中如何避免重复的数据库连接?