我是数据库和 SQL 的新手,从 3 天起就试图解决这个问题。我有一个 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
Run Code Online (Sandbox Code Playgroud)
我的目标是获得大多数 comlumns 匹配的行,如果没有列匹配,则应选择第 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
Run Code Online (Sandbox Code Playgroud)
到目前为止我最好的猜测是这个查询
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;
Run Code Online (Sandbox Code Playgroud)
?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;
Run Code Online (Sandbox Code Playgroud)
Matchescolumn 将计算所有列匹配或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;
Run Code Online (Sandbox Code Playgroud)
优点:你也可以比较NULL。缺点:找到排名相同的匹配项时,仅显示 1 个匹配项。
| 归档时间: |
|
| 查看次数: |
2101 次 |
| 最近记录: |