SQL:测试数字是否包含其他数字的数字
我对使用SQL测试存储在DOW列中的一个数字是否包含同样存储在DOW中的另一个数字的数字感兴趣,而不考虑其他数字的分隔。以下是我目前正在处理的数据,尽管我将来可能会有更多的数据需要处理: 二十三 236 1234 12346 123456 67 如果查询检查123456与236,则需要返回true。反之亦然,236对123456返回false。另一个示例是,1234在与23进行检查时返回true,而67在与12346进行检查时返回false。如果我在这个问题上没有提供足够的信息,请要求澄清 我的查询的简化版本:SQL:测试数字是否包含其他数字的数字,sql,Sql,我对使用SQL测试存储在DOW列中的一个数字是否包含同样存储在DOW中的另一个数字的数字感兴趣,而不考虑其他数字的分隔。以下是我目前正在处理的数据,尽管我将来可能会有更多的数据需要处理: 二十三 236 1234 12346 123456 67 如果查询检查123456与236,则需要返回true。反之亦然,236对123456返回false。另一个示例是,1234在与23进行检查时返回true,而67在与12346进行检查时返回false。如果我在这个问题上没有提供足够的信息,请要求澄清 我的
SELECT t1.DOW, t2.DOW
FROM table t1, table t2
WHERE /* t2.DOW contains all digits regardless of separation in t1.DOW */
谢谢 这可以作为一个存储过程来处理,该过程将值转换为字符串,并检查模式值中每个数字的字符串 存储过程的核心将是
function has_digits (pattern, value)
string s = string (value)
count = 0
for each char in pattern
if instr (s, char) > 0 // for mysql
count = count + 1
return count == pattern.length()
这在很大程度上取决于使用哪种SQL风格。
这将像
SELECT *
FROM sometable
WHERE has_digits (236, somefield);
仅适用于MySQL:
然后,您可以使用这个可怕的查询,它首先将数字转换为字符串,并在每个数字之间加上%。23将转换为“%2%3%”,然后测试23456中类似“%2%3%”的位置,以匹配23456是否包含23:
SELECT t1.DOW
, t2.DOW
, (t1.DOW LIKE test) AS t1_contains_t2
FROM t1
JOIN
( SELECT t2.DOW
, CONCAT( '%'
, GROUP_CONCAT( SUBSTRING( t2.DOW, num.i, 1 )
ORDER BY num.i
SEPARATOR '%' )
, '%'
) AS test
FROM t2
JOIN num
ON (SUBSTRING(t2.DOW,num.i,1) != "" )
GROUP BY t2.DOW
) AS temp ;
t1_contains_t2列将具有1或0,具体取决于t1.DOW是否包含t2.DOW
或者您可以在查询中使用WHERE t1.DOW-LIKE测试。我假设DOW是一周中的一天,并且只有数字1-7
SQL Server 2008的答案虽然这是标准SQL。首先,我想确保每个人都明白,我坚信这应该在存储过程中。而且,我可能会花明天的大部分时间,试图为我将要写的东西找出一个合适的惩罚 假设我们有两张桌子。第一个表包含我们要搜索的数字
CREATE TABLE search_digits (
digit integer NOT NULL
);
INSERT INTO search_digits VALUES (2), (3);
我们要搜索数字2和3
第二个表包含我们要在其中搜索的值
CREATE TABLE dow_digits (
dow integer NOT NULL,
digit integer NOT NULL,
CONSTRAINT dow_digits_pkey PRIMARY KEY (dow, digit),
);
INSERT INTO dow_digits VALUES (23, 2);
INSERT INTO dow_digits VALUES (23, 3);
INSERT INTO dow_digits VALUES (236, 2);
INSERT INTO dow_digits VALUES (236, 3);
INSERT INTO dow_digits VALUES (236, 6);
INSERT INTO dow_digits VALUES (1234, 1);
INSERT INTO dow_digits VALUES (1234, 2);
INSERT INTO dow_digits VALUES (1234, 3);
INSERT INTO dow_digits VALUES (1234, 4);
INSERT INTO dow_digits VALUES (12346, 1);
INSERT INTO dow_digits VALUES (12346, 2);
INSERT INTO dow_digits VALUES (12346, 3);
INSERT INTO dow_digits VALUES (12346, 4);
INSERT INTO dow_digits VALUES (12346, 6);
INSERT INTO dow_digits VALUES (123456, 1);
INSERT INTO dow_digits VALUES (123456, 2);
INSERT INTO dow_digits VALUES (123456, 3);
INSERT INTO dow_digits VALUES (123456, 4);
INSERT INTO dow_digits VALUES (123456, 5);
INSERT INTO dow_digits VALUES (123456, 6);
INSERT INTO dow_digits VALUES (67, 6);
INSERT INTO dow_digits VALUES (67, 7);
我们可以通过一个简单的查询找到至少一些包含数字2和3的dow值
select d1.dow from dow_digits d1
inner join search_digits d2 on d1.digit = d2.digit
group by dow
having count(distinct d1.digit) = (select count(distinct digit)
from search_digits);
dow
--
23
236
1234
12346
123456
这似乎奏效了。如果搜索整数是233,OP的期望值是多少还不清楚,所以我现在不考虑这种情况。我想快点完成,然后走到卡车前面
下一个问题是,我们可以动态构建搜索数字吗?在PostgreSQL中,有点像
SELECT UNNEST(ARRAY[2,3]) as digit;
digit
--
2
3
删除表格搜索数字,并将其包装在CTE中
with search_digits as (
select unnest(array[2,3]) as digit
)
select d1.dow from dow_digits d1
inner join search_digits d2 on d1.digit = d2.digit
group by dow
having count(distinct d1.digit) = (select count(distinct digit)
from search_digits);
dow
--
23
236
1234
12346
123456
下一个问题。我们能在飞行中建立道指吗?在PostgreSQL中,有点像。需要知道最长数字中有多少位。让我们说不超过六个
select dow, digit
from (select dow, unnest(array[substring((dow)::text from 1 for 1),
substring((dow)::text from 2 for 1),
substring((dow)::text from 3 for 1),
substring((dow)::text from 4 for 1),
substring((dow)::text from 5 for 1),
substring((dow)::text from 6 for 1)]) digit
from dow ) d
where d.digit <> '';
dow digit
--
23 2
23 3
236 2
236 3
236 6
1234 1
1234 2
1234 3
1234 4
12346 1
12346 2
12346 3
12346 4
12346 6
123456 1
123456 2
123456 3
123456 4
123456 5
123456 6
67 6
67 7
233 2
233 3
233 3
把所有这些放在一起形成一个陈述
with search_digits as (
select unnest(array[1,2,3,4,6]) digit
)
select dow
from (select dow, digit
from (select dow, unnest(array[substring((dow)::text from 1 for 1),
substring((dow)::text from 2 for 1),
substring((dow)::text from 3 for 1),
substring((dow)::text from 4 for 1),
substring((dow)::text from 5 for 1),
substring((dow)::text from 6 for 1)]) digit
from dow
) arr
where arr.digit <> ''
) d
inner join (select distinct digit from search_digits) sd
on sd.digit = d.digit::integer
group by dow
having count(distinct d.digit) = (select count(distinct digit)
from search_digits)
dow
--
12346
123456
哦,我能感觉到因果报应在悄悄溜走。那辆卡车在哪里?SQL在模拟数组方面特别差。您最好使用另一个工具。@le dorfier:表,无论是派生的还是其他的,都是一个数组……这部分对我来说没有意义:如果查询将123456与236进行比较,它需要返回true。反之亦然,236对123456返回false。所有四个数字都包含数字2、3和6。可能是打字错误?@Catcall-123456包含236的所有数字,但不包含236的所有数字。将233与1234进行比较,应该返回true还是false?233的所有数字都包含在1234中,但在第一个数字中有更多的3。@David-我没有任何标准的副本。快速谷歌显示表值构造函数位可能不是标准的-但是可以很容易地用一组联合所有替换。编辑:-经过再三考虑,此答案表明此网站是新的SQL 2003标准,没有足够的代表投票支持您的答案。你帮了我很多忙,谢谢。
select dow, digit
from (select dow, unnest(array[substring((dow)::text from 1 for 1),
substring((dow)::text from 2 for 1),
substring((dow)::text from 3 for 1),
substring((dow)::text from 4 for 1),
substring((dow)::text from 5 for 1),
substring((dow)::text from 6 for 1)]) digit
from dow ) d
where d.digit <> '';
dow digit
--
23 2
23 3
236 2
236 3
236 6
1234 1
1234 2
1234 3
1234 4
12346 1
12346 2
12346 3
12346 4
12346 6
123456 1
123456 2
123456 3
123456 4
123456 5
123456 6
67 6
67 7
233 2
233 3
233 3
with search_digits as (
select unnest(array[1,2,3,4,6]) digit
)
select dow
from (select dow, digit
from (select dow, unnest(array[substring((dow)::text from 1 for 1),
substring((dow)::text from 2 for 1),
substring((dow)::text from 3 for 1),
substring((dow)::text from 4 for 1),
substring((dow)::text from 5 for 1),
substring((dow)::text from 6 for 1)]) digit
from dow
) arr
where arr.digit <> ''
) d
inner join (select distinct digit from search_digits) sd
on sd.digit = d.digit::integer
group by dow
having count(distinct d.digit) = (select count(distinct digit)
from search_digits)
dow
--
12346
123456