我是数据库和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
我的目标是获取大多数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
到目前为止,我最好的猜测是这个查询
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不支持这个。
我希望我能够准确地描述这个问题。任何帮助将不胜感激。
答案 0 :(得分:4)
这应该可以解决问题:
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
。优势:当找到同等排名的匹配时,只显示一场比赛。