MySQL字符串与百分比输出的比较
我试图比较两个6个数字的条目,每个数字可以是0或1(即100001或011101)。如果六分之三匹配,我希望输出为.5。如果6个匹配中有2个匹配,我希望输出为.33等 下面是创建表的SQL命令MySQL字符串与百分比输出的比较,sql,mysql,string-comparison,Sql,Mysql,String Comparison,我试图比较两个6个数字的条目,每个数字可以是0或1(即100001或011101)。如果六分之三匹配,我希望输出为.5。如果6个匹配中有2个匹配,我希望输出为.33等 下面是创建表的SQL命令 CREATE TABLE sim (sim_key int, string int); INSERT INTO sim (sim_key, string) VALUES (1, 111000); INSERT INTO sim (sim_key, string) VALUES (2, 111111)
CREATE TABLE sim
(sim_key int,
string int);
INSERT INTO sim (sim_key, string)
VALUES (1, 111000);
INSERT INTO sim (sim_key, string)
VALUES (2, 111111);
我想要的输出是比较两个字符串(共享50%的字符)和输出50%
可以在SQL中进行这种比较吗?提前感谢因为您将它们存储为数字,所以您可以这样做
SELECT BIT_COUNT(s1.string & s2.string) / BIT_COUNT(s1.string | s1.string)
FROM sim s1, sim s2
WHERE s1.sim_key = 1 AND s2.sim_key = 2
这将返回两个字符串中相等1位的百分比:
select bit_count(conv(a.string, 2, 10) & conv(b.string, 2, 10))/6*100 as percent_match
from sim a, sim b where
a.sim_key=1 and b.sim_key=2;
当您将位字段存储为转换为数字的基2表示形式时,我们首先需要进行转换:conv(a.string,2,10)
,conv(b.string,2,10)
然后我们在每个字段中只保留1位:conv(a.string,2,10)&conv(b.string,2,10)
我们计算它们:bit\u计数(conv(a.string,2,10)和conv(b.string,2,10))
最后我们只需计算百分比:位计数(conv(a.string,2,10)&conv(b.string,2,10))/6*100
对于111000
和111111
,查询返回50
以下是另一个也计算匹配零的版本:
select bit_count((conv(a.string, 2, 10) & conv(b.string, 2, 10)) | ((0xFFFFFFFF>>(32-6))&~(conv(a.string, 2, 10)|conv(b.string, 2, 10))))/6*100 as percent_match
from sim a, sim b where
a.sim_key=1 and b.sim_key=2;
请注意,虽然此解决方案有效,但您实际上应该这样存储此字段:
INSERT INTO sim (sim_key, string)
VALUES (1, conv("111000", 2, 10));
INSERT INTO sim (sim_key, string)
VALUES (2, conv("111111", 2, 10));
或更新现有数据:
UPDATE sim SET string=conv(string, 10, 2);
然后,此查询将给出相同的结果(如果您按照上述方式更新了数据):
还要数零:
select bit_count((a.string & b.string) | ((0xFFFFFFFF>>(32-6))&~(a.string|b.string)))/6*100 as percent_match
from sim a, sim b where
a.sim_key=1 and b.sim_key=2;
(用您的位域大小替换
6
s)您能以表格格式发布一些示例数据和所需的输出吗?您能详细解释一下这个问题吗?这两个数字是出现在表中的同一行,还是来自两个不同行中的同一列?我的感觉是这是可能的,“如何”取决于这些数字来自哪里。它需要在MySQL中进行计算,这样就不会使用索引-这会使查询大型数据集(返回大量行)的速度变慢,但如果您只直接比较两个数字就可以了。看起来像二进制数据-您可以使用binary/varbinary类型吗?您是否将它们保存为字符串(或零填充整数)以保留前导零?创建表是否有助于解释我要做的事情?这基本上是二进制数据。如何与二进制数据进行比较?在(111000111111)上返回0.3333;-)您正在将二进制11
存储为11?经过大量分析,我发现这并不是我想要的。指出位置也很重要这一点很重要。该解决方案应该考虑位置。哪些字符串不起作用?&
(按位and)运算符只保留两个操作数中位于相同位置的1位。然后,bit\u count()
函数只对它们进行计数。因此,这计算两个字符串中相同位置的1位。例如,它不适用于值111000和101011。它返回67%的分数,而不是50%。实际上,它应该返回33.33%(2/6)。答案中的查询返回33.33%:将111000和101011中的位保持在同一位置会得到101000。所以2位是相等的。除以6,乘以100->33.33%。(请注意,我在答案中给出的最后一个查询只有在您也相应地更新了数据时才有效;如果没有,就使用第一个查询。)否,因为我想将匹配的零也计算为匹配项。也许我没有在我的问题中正确地解释这一点。
select bit_count((a.string & b.string) | ((0xFFFFFFFF>>(32-6))&~(a.string|b.string)))/6*100 as percent_match
from sim a, sim b where
a.sim_key=1 and b.sim_key=2;