4

私はデータベースと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 はそれをサポートしていないため、ストアド プロシージャがこの問題に適している場合は、データベースを変更できます。

問題を十分に正確に説明したことを願っています。どんな助けでも大歓迎です。

4

1 に答える 1

6

これでうまくいくはずです:

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;

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;

メリット:比較NULLもできる 欠点: ランクが同程度の一致が見つかった場合、1 つの一致のみが表示されます。

于 2013-10-24T09:49:16.370 に答える