检查项目集是否出现在行 MySQL 中
Check if set of items occurrs in row MySQL
我正在 MySQL 中处理大数据集(结合 Java)并尝试实现频繁项集算法。
该算法的一个重复方面是计算一组项目(一个项目是一个随机整数)在数据集中出现的次数。
以这个小数据集为例 T:
ID | COL1 | COL2 | COL3 | COL4 | COL5 |
---------------------------------------
1 | 8 | 35 | 42 | 12 | 27 |
2 | 22 | 42 | 35 | 8 | NULL |
3 | 18 | 22 | 8 | NULL | NULL |
4 | 42 | 12 | 27 | 35 | 8 |
5 | 18 | 27 | 12 | 22 | NULL |
还有这个tableT2:
COL1 | COL2 |
-------------
35 | 27 |
22 | 8 |
42 | 8 |
18 | 35 |
35 | 42 |
我想要的结果是以下table(它也可以是查询的答案):
COL1 | COL2 | COUNT |
---------------------
35 | 27 | 2 |
22 | 8 | 2 |
42 | 8 | 3 |
18 | 35 | 0 |
35 | 42 | 3 |
所以我想统计 table T2 在 table T 中每一行的每次出现。基本上 T2 行是 T
行的子集多少次
每一代算法都必须这样做。这是一个非常小的示例,最终必须对 T3(具有 3 个项目的行)、T4(具有 4 个项目的行)进行相同的操作等 Table T 保持不变。
我还必须考虑到顺序无关紧要(|35、27| = |27、35|),并且它们可能不会在 T[=40 中彼此相邻的列中=]
是否可以在不遍历数据集太多次的情况下执行此操作(而 太多 = 超过 T2[=40 中的行数=])?
将一行表示为一个元组(例如 (35, 27))可能会更好,这样它就变成了一个项目?
如果您可以将数据重组为每行一个值,对于 T 和 TN,这样的事情应该同时适用于所有 TN。
SELECT n_id, COUNT(CASE WHEN matches = n_count THEN v_id ELSE NULL) AS occurences
FROM (
SELECT n.n_id, v.set_id AS v_id, n.n_count, COUNT(*) AS matches
FROM (SELECT n_id, COUNT(*) AS n_count FROM tN GROUP BY id) AS n
INNER JOIN tN AS nv ON n.n_id = nv.n_id
LEFT JOIN T_VALUES AS v ON nv.value = v.value
GROUP BY n.n_id, v.set_id, n.n_count
) AS subQ;
如果您在最终结果中需要 TN 值,类似这样的结果会很接近。
SELECT n_id, n_values, COUNT(CASE WHEN matches = n_count THEN v_id ELSE NULL) AS occurences
FROM (
SELECT n.n_id, n.n_count, n.n_values, v.set_id AS v_id, COUNT(*) AS matches
FROM (
SELECT n_id, COUNT(*) AS n_count
, GROUP_CONCAT(n.value) AS n_values
FROM tN
GROUP BY id
) AS n
INNER JOIN tN AS nv ON n.n_id = nv.n_id
LEFT JOIN T_VALUES AS v ON nv.value = v.value
GROUP BY n.n_id, n.n_count, n.n_values, v.set_id
) AS subQ;
注意:您可能不用子查询就可以逃脱,但最终可能会让数据库为 T 的每一行重复计算相同的 n_count 和 n_values。
由于 Uueerdo 的回答,我意识到我必须使用不同的结构,所以我没有使用 table T:
ID | COL1 | COL2 | COL3 | COL4 | COL5 |
---------------------------------------
1 | 8 | 35 | 42 | 12 | 27 |
2 | 22 | 42 | 35 | 8 | NULL |
3 | 18 | 22 | 8 | NULL | NULL |
4 | 42 | 12 | 27 | 35 | 8 |
5 | 18 | 27 | 12 | 22 | NULL |
我现在用Tnew:
ID | Item|
1 | 8 |
1 | 35 |
1 | 42 |
. | . |
. | . |
. | . |
这在 SQL 中更容易工作,您可以使用分组依据和联接来获得所需的结果。该查询适用于具有相同 ID 的任意数量的项目。此外,您不必使用值 NULL 并且数据集更容易创建
如果有人想知道我最终使用的查询,请告诉我(想出好的 table 名称并使其清晰易懂需要做一些工作)。
我正在 MySQL 中处理大数据集(结合 Java)并尝试实现频繁项集算法。 该算法的一个重复方面是计算一组项目(一个项目是一个随机整数)在数据集中出现的次数。
以这个小数据集为例 T:
ID | COL1 | COL2 | COL3 | COL4 | COL5 |
---------------------------------------
1 | 8 | 35 | 42 | 12 | 27 |
2 | 22 | 42 | 35 | 8 | NULL |
3 | 18 | 22 | 8 | NULL | NULL |
4 | 42 | 12 | 27 | 35 | 8 |
5 | 18 | 27 | 12 | 22 | NULL |
还有这个tableT2:
COL1 | COL2 |
-------------
35 | 27 |
22 | 8 |
42 | 8 |
18 | 35 |
35 | 42 |
我想要的结果是以下table(它也可以是查询的答案):
COL1 | COL2 | COUNT |
---------------------
35 | 27 | 2 |
22 | 8 | 2 |
42 | 8 | 3 |
18 | 35 | 0 |
35 | 42 | 3 |
所以我想统计 table T2 在 table T 中每一行的每次出现。基本上 T2 行是 T
行的子集多少次每一代算法都必须这样做。这是一个非常小的示例,最终必须对 T3(具有 3 个项目的行)、T4(具有 4 个项目的行)进行相同的操作等 Table T 保持不变。 我还必须考虑到顺序无关紧要(|35、27| = |27、35|),并且它们可能不会在 T[=40 中彼此相邻的列中=]
是否可以在不遍历数据集太多次的情况下执行此操作(而 太多 = 超过 T2[=40 中的行数=])? 将一行表示为一个元组(例如 (35, 27))可能会更好,这样它就变成了一个项目?
如果您可以将数据重组为每行一个值,对于 T 和 TN,这样的事情应该同时适用于所有 TN。
SELECT n_id, COUNT(CASE WHEN matches = n_count THEN v_id ELSE NULL) AS occurences
FROM (
SELECT n.n_id, v.set_id AS v_id, n.n_count, COUNT(*) AS matches
FROM (SELECT n_id, COUNT(*) AS n_count FROM tN GROUP BY id) AS n
INNER JOIN tN AS nv ON n.n_id = nv.n_id
LEFT JOIN T_VALUES AS v ON nv.value = v.value
GROUP BY n.n_id, v.set_id, n.n_count
) AS subQ;
如果您在最终结果中需要 TN 值,类似这样的结果会很接近。
SELECT n_id, n_values, COUNT(CASE WHEN matches = n_count THEN v_id ELSE NULL) AS occurences
FROM (
SELECT n.n_id, n.n_count, n.n_values, v.set_id AS v_id, COUNT(*) AS matches
FROM (
SELECT n_id, COUNT(*) AS n_count
, GROUP_CONCAT(n.value) AS n_values
FROM tN
GROUP BY id
) AS n
INNER JOIN tN AS nv ON n.n_id = nv.n_id
LEFT JOIN T_VALUES AS v ON nv.value = v.value
GROUP BY n.n_id, n.n_count, n.n_values, v.set_id
) AS subQ;
注意:您可能不用子查询就可以逃脱,但最终可能会让数据库为 T 的每一行重复计算相同的 n_count 和 n_values。
由于 Uueerdo 的回答,我意识到我必须使用不同的结构,所以我没有使用 table T:
ID | COL1 | COL2 | COL3 | COL4 | COL5 |
---------------------------------------
1 | 8 | 35 | 42 | 12 | 27 |
2 | 22 | 42 | 35 | 8 | NULL |
3 | 18 | 22 | 8 | NULL | NULL |
4 | 42 | 12 | 27 | 35 | 8 |
5 | 18 | 27 | 12 | 22 | NULL |
我现在用Tnew:
ID | Item|
1 | 8 |
1 | 35 |
1 | 42 |
. | . |
. | . |
. | . |
这在 SQL 中更容易工作,您可以使用分组依据和联接来获得所需的结果。该查询适用于具有相同 ID 的任意数量的项目。此外,您不必使用值 NULL 并且数据集更容易创建
如果有人想知道我最终使用的查询,请告诉我(想出好的 table 名称并使其清晰易懂需要做一些工作)。