Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-选择具有大多数匹配列的行_Sql_Sqlite_Jdbc - Fatal编程技术网

SQL-选择具有大多数匹配列的行

SQL-选择具有大多数匹配列的行,sql,sqlite,jdbc,Sql,Sqlite,Jdbc,我是数据库和SQL的新手,从3天开始就在尝试解决这个问题。我有一个用JDBC查询SQLite数据库的Java应用程序。到目前为止,这个效果很好。但是我无法找到检索所需行所需的SQL查询。该表如下所示: rowid | application | dstIP | dstPort | value_to_return | | | | 0 | NULL | NULL

我是数据库和SQL的新手,从3天开始就在尝试解决这个问题。我有一个用JDBC查询SQLite数据库的Java应用程序。到目前为止,这个效果很好。但是我无法找到检索所需行所需的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;
用相应的输入值替换?s。如果不匹配,此查询将返回第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

groupby
不使用聚合函数将捕获第一行(我希望!),这是最大匹配,因为内部查询按降序排序

编辑:新版本:

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个匹配项。

看起来不错,但我无法测试它。它说在WHERE附近有语法错误。我对SQL太没经验了:(我现在正在测试内部SELECT。当一列没有匹配项时,这似乎不起作用,因为ELSE NULL分支。然后匹配项列应该是2,但它是NULL。但我知道了它的基本原理。给我一点时间=)当比赛排名相等时,我会选择返回的最大值,所以这应该没有问题。给我一点时间来测试它=)很好,我得到了几乎相同的结果,我在你的答案中编辑了它。谢谢你的帮助!您可以在SQL中为操作添加“虚拟行”,这让我很困惑