python sqlite 字符串比较
python sqlite string comparison
我有一个在 table 中包含多行的 sqlite 数据库。其中一列包含具有任意数量正整数的字符串,因此:
1: '### ## # # # ## # ##'
2: '# ## # ## # ##'
3: '# # # ## ## ### #'
...
我的 python 代码中也有一个比较字符串,它看起来也像“## # ### #”
比较字符串还包含任意数量的正整数。
现在,如果我们将数据库字符串设为 'a b c d e f' 并将我们的比较字符串设为 'g h i j k'
例如,我需要测试比较字符串中的任何 3 个连续数字(因此 'g h i' 或 'h i j' 或 'i j k')是否也是数据库中的连续数字。所以基本上我需要测试数据库中的每一行 if
'g h i' == 'a b c' or 'g h i' == 'b c d' or ...
我的数据当前保存在数据库中的方式是否可行,或者我是否需要以任何其他方式保存我的数据。无论哪种方式,我如何使用 SQL?
来做到这一点
我会为您的table提出不同的设计方案。
而不是像这样存储数字:
grp
value
1
'10 100 20 5 70'
2
'100 20 5 35 3 15'
您可以规范化 table 以便每行仅包含 1 个值:
id
grp
value
1
1
10
2
1
100
3
1
20
4
1
5
5
1
70
6
2
100
7
2
20
8
2
5
9
2
35
10
2
3
11
2
15
这样可以更轻松地连接连续的数字(三元组或其他任何形式),以便您可以检查连接的数字是否包含在您的字符串中。
创建 table:
CREATE TABLE tablename(id INTEGER PRIMARY KEY AUTOINCREMENT, grp INTEGER, value INTEGER);
并且对于每一行使用 window 函数 LEAD()
来获取下一个数字和之后的数字,以便创建一个串联的三元组。
然后您可以使用运算符 LIKE
检查字符串中是否存在三元组:
WITH cte AS (
SELECT *,
value || ' ' ||
LEAD(value, 1) OVER (PARTITION BY grp ORDER BY id) || ' ' ||
LEAD(value, 2) OVER (PARTITION BY grp ORDER BY id) str
FROM tablename
)
SELECT grp, MAX(' ' || ? || ' ' LIKE '% ' || str || ' %') flag
FROM cte
GROUP BY grp;
或者,更好的可扩展解决方案:
WITH cte AS (
SELECT *,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY grp ORDER BY id) > 2
THEN GROUP_CONCAT(value, ' ') OVER (
PARTITION BY grp ORDER BY id
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
)
END str
FROM tablename
)
SELECT grp, MAX(' ' || '6 100 20 5 12 19' || ' ' LIKE '% ' || str || ' %') flag
FROM cte
GROUP BY grp;
用您的字符串替换 ?
。
查看简化版 demo.
我有一个在 table 中包含多行的 sqlite 数据库。其中一列包含具有任意数量正整数的字符串,因此:
1: '### ## # # # ## # ##'
2: '# ## # ## # ##'
3: '# # # ## ## ### #'
...
我的 python 代码中也有一个比较字符串,它看起来也像“## # ### #” 比较字符串还包含任意数量的正整数。
现在,如果我们将数据库字符串设为 'a b c d e f' 并将我们的比较字符串设为 'g h i j k' 例如,我需要测试比较字符串中的任何 3 个连续数字(因此 'g h i' 或 'h i j' 或 'i j k')是否也是数据库中的连续数字。所以基本上我需要测试数据库中的每一行 if
'g h i' == 'a b c' or 'g h i' == 'b c d' or ...
我的数据当前保存在数据库中的方式是否可行,或者我是否需要以任何其他方式保存我的数据。无论哪种方式,我如何使用 SQL?
来做到这一点我会为您的table提出不同的设计方案。
而不是像这样存储数字:
grp | value |
---|---|
1 | '10 100 20 5 70' |
2 | '100 20 5 35 3 15' |
您可以规范化 table 以便每行仅包含 1 个值:
id | grp | value |
---|---|---|
1 | 1 | 10 |
2 | 1 | 100 |
3 | 1 | 20 |
4 | 1 | 5 |
5 | 1 | 70 |
6 | 2 | 100 |
7 | 2 | 20 |
8 | 2 | 5 |
9 | 2 | 35 |
10 | 2 | 3 |
11 | 2 | 15 |
这样可以更轻松地连接连续的数字(三元组或其他任何形式),以便您可以检查连接的数字是否包含在您的字符串中。
创建 table:
CREATE TABLE tablename(id INTEGER PRIMARY KEY AUTOINCREMENT, grp INTEGER, value INTEGER);
并且对于每一行使用 window 函数 LEAD()
来获取下一个数字和之后的数字,以便创建一个串联的三元组。
然后您可以使用运算符 LIKE
检查字符串中是否存在三元组:
WITH cte AS (
SELECT *,
value || ' ' ||
LEAD(value, 1) OVER (PARTITION BY grp ORDER BY id) || ' ' ||
LEAD(value, 2) OVER (PARTITION BY grp ORDER BY id) str
FROM tablename
)
SELECT grp, MAX(' ' || ? || ' ' LIKE '% ' || str || ' %') flag
FROM cte
GROUP BY grp;
或者,更好的可扩展解决方案:
WITH cte AS (
SELECT *,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY grp ORDER BY id) > 2
THEN GROUP_CONCAT(value, ' ') OVER (
PARTITION BY grp ORDER BY id
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
)
END str
FROM tablename
)
SELECT grp, MAX(' ' || '6 100 20 5 12 19' || ' ' LIKE '% ' || str || ' %') flag
FROM cte
GROUP BY grp;
用您的字符串替换 ?
。
查看简化版 demo.