2017-06-26 4 views
0

MySQLの文字列(パスワード)の列を与えられ、値がNであると仮定して、各nグラムの頻度をカウントするSQLの方法を探しています(長さの部分文字列n)。MySQLの単一列nグラムの分割とカウント

私が持っている他の環境では、コードがMySQLの内部に保存されていることが重要です。その結果、メモリがオーバーフローします。私がその間見出さ

ザのみ作動アプローチは、13個の文字のうち、9グラムのために(このように、union、次いでgroup bycount、異なる位置のサブストリングを抽出することによって別々にselect、ストリング(合法的な仮定)の限られた長さを想定しています):

Select 
    nueve, 
    count(*) as density, 
    avg(location) as avgloc 

From 
    (select 
     mid(pass, 1, 9) as nueve, 1 as location 
    from 
     passdata 
    where 
     length(pass) >= 9 and length(pass) <= 13 UNION ALL select 
     mid(pass, 2, 9), 2 as location 
    from 
     passdata 
    where 
     length(pass) >= 10 and length(pass) <= 13 UNION ALL select 
     mid(pass, 3, 9), 3 as location 
    from 
     passdata 
    where 
     length(pass) >= 11 and length(pass) <= 13 UNION ALL select 
     mid(pass, 4, 9), 4 as location 
    from 
     passdata 
    where 
     length(pass) >= 12 and length(pass) <= 13 UNION ALL select 
     mid(pass, 5, 9), 5 as location 
    from 
     passdata 
    where 
     length(pass) = 13) as nueves 
group by nueve 
order by density DESC 

結果は次のように探しています:

nueve  density avgloc 
123456789 1387 2.4564 
234567890 193  2.7306 
987654321 141  2.0355 
password1 111  1.7748 
123123123 92  1.913 
liverpool 89  1.618 
111111111 86  2.2791 

nueveは9グラムであり、densityは出現回数で、avglocは、文字列

クエリを改善するための任意の提案で開始位置を平均ですか?他のn-gramについても同じことをしています。

ありがとうございます!

答えて

1

1からパスワードの最大長までのすべての数字を含む表を作成します。これで、サブストリングの位置を取得することができます。

SELECT nueve, COUNT(*) AS density, AVG(location) as avgloc 
FROM (
    SELECT MID(p.pass, n.num, @N) AS nueve, n.num AS location 
    FROM passdata AS p 
    JOIN numbers_table AS n ON LENGTH(p.pass) >= (@N + n.num - 1) 
) AS x 
GROUP BY nueve 
ORDER BY density DESC 
+0

ありがとう、それは非常に賢いです!私はそれを言葉にも使うと思う。 – Dimgold

+0

SQLの唯一の実際の反復処理方法は結合であるため、あらゆる種類の数値反復処理に役立ちます。 – Barmar

関連する問題