我有一个uuid存储在一个表中作为人类可读的guid,但在另一个表中它分为上部和下部位.如何编写查询以加入uuid上的表?
编辑:table2只有1个结果与给定的上限&较低的位,所以希望效率不要太可怕,但请把它考虑成答案.
table1.uuid = 'b33ac8a9-ae45-4120-bb6e-7537e271808e'
table2.upper_bits = -5531888561172430560, table2.lower_bits = -4940882858296115058
我需要检索table2.status以及table1.* where table2.upper_bits table2.lower_bits = table1.uuid(pseudo where statement)但我不知道如何对table2 upper和amp;较低的连接值,或者如何将table1的uuid转换为连接的位.
谢谢!
解决方法:
像这样的东西可能会起作用……但显然效率很低.
SELECT ...
FROM table1 AS t1
INNER JOIN table2 AS t2 ON REPLACE(t1.uuid, '-', '')
= CONCAT(HEX(t2.upper_bits), HEX(t2.lower_bits))
...
…你可能会根据整理/比较强制大/小写.
我倾向于改变你的数据库结构“(绝对有必要”)来回应你在另一个答案上做出的评论.为了最小化对现有查询和逻辑的影响,您可以更改其中一个表以使另一个表具有其他匹配字段,并向表中添加触发器以自动填充/更新新字段;然后执行一次更新以设置所有旧记录的值.
我试着先修改t1,因为两个整数的索引可能比一个字符串“更好”;但我不确定如何将字符串直接转换为高位和低位.
修改t2会更容易,触发器只会比SET NEW.uuid = CONCAT(HEX(NEW.upper_bits),HEX(NEW.lower_bits)); …我说“仅仅是”,因为触发器最好也在预期的位置插入-s,因此连接条件可以消除所有功能使用.
编辑:我找到了一种计算纯SQL中的位的方法:
SELECT @uuid := REPLACE('b33ac8a9-ae45-4120-bb6e-7537e271808e', '-', '') AS uuid
, -1 * CAST((~CAST(CONV(SUBSTRING(@uuid, 1, 16), 16, 10) AS SIGNED) + 1) AS SIGNED) AS upper_bits
, -1 * CAST((~CAST(CONV(SUBSTRING(@uuid, 17, 16), 16, 10) AS SIGNED) + 1) AS SIGNED) AS lower_bits
;
你可以在t1的触发器中使用这样的东西,为新字段使用t1的一次更新.
……它甚至可能有助于加入:
ON -1 * CAST((~CAST(CONV(SUBSTRING(REPLACE(t1.uuid, '-', ''), 1, 16), 16, 10) AS SIGNED) + 1) AS SIGNED)
= t2.upper_bits
AND -1 * CAST((~CAST(CONV(SUBSTRING(REPLACE(t1.uuid, '-', ''), 17, 16), 16, 10) AS SIGNED) + 1) AS SIGNED)
= t2.lower_bits
注意:是的,这两个中的过度投射似乎是必要的(至少在我测试计算的MySQL的旧版本上.)