问题在于: 订单由from和to日期以及2个bitmask文件表示。 一个表示FromDate和ToDate之间的有序日期,第二个表示订单对于给定日期有效的数据 可能会对该顺序进行修改,这些修改由原始FromDate和ToDate的子集以及位掩码字段表示。 诀窍在于,当修改只发送一部分位掩码时
create table orders
(
ref_id int,
DateFrom datetime,
DateTo datetime,
version int,
DateBitmask varchar(255),
DataBitmask varchar(255)
)
示例数据:
ref_id DateFrom DateTo Version DateBitmap DataBitmap
1 20150801 20150810 0 0011101110 0000101100
1 20150810 20150810 1 1 1
1 20150803 20150804 2 11
1 20150810 20150810 3 1 0
我正在寻找的结果是Databitmap字段的一种历史“运行总和”,最终得到了DataBitmap的最新实际状态。 实际上,我们发现实现此目的的唯一方法是通过整个数据库并检查所有ref_id所有修改,更新该ref_id的临时值,最后得到最终结果。
为了给您一个提示,给定示例的最终结果将是0011101100
因为初始数据是0000101100
这首先修改了最后一个位置,它给了我们0000101101
比第2和第3位修改了它给了我们0011101101
在为我们提供0011101100
如何快速优雅地实现这一目标? 托管这些数据的表格相当大(50-60 Mio记录)并且变得更大。
在有人建议我们改变表格结构之前,不幸的是我们不能。
有什么想法吗?
答案 0 :(得分:0)
好的,所以我会尝试覆盖它,希望它足够好,或者至少它可以帮助你。
因此,您需要进行一些替换和简单操作,并使用按位运算符,因为您具有该结构。我们将二进制值转换为小数,对它们进行操作然后将它们转换回二进制。您的示例上的应用程序将是:
SELECT BIN(CONV(BINARY('0000101100'), 2, 10) + CONV(BINARY('0000000001'), 2, 10) + CONV(BINARY('0011000000'), 2, 10) + CONV(BINARY('1111111110'), 2, 10) - 1023);
所以,正如您所看到的,我刚从DataBitmap
对您的信息进行了总结,并将空格替换为0.如果您的DataBitmap
中有0,我们必须更换空白空格为1,然后减去1023(2 ^ 10 - 1)。当然你可以消除第一个1的左边,这样就可以了:
SELECT BIN(CONV(BINARY('101100'), 2, 10) + CONV(BINARY('1'), 2, 10) + CONV(BINARY('11000000'), 2, 10) + CONV(BINARY('1111111110'), 2, 10) - 1023);
MySQL中的结果是11101100
女巫也是你的结果,没有前2 0
。
如果你在同一行上也有1和0,你需要将该行分成一行,只有0而一行只有1,并在其上应用2个操作。
例如,如果你有:
ref_id DateFrom DateTo Version DateBitmap DataBitmap
1 20150801 20150810 0 0011101110 0000101100
1 20150810 20150810 1 1 011
应该翻译成:
ref_id DateFrom DateTo Version DateBitmap DataBitmap
1 20150801 20150810 0 0011101110 0000101100
1 20150810 20150810 1 1 11
1 20150810 20150810 1 1 0
然后我们可以:
SELECT BIN(CONV(BINARY('0000101100'), 2, 10) + CONV(BINARY('11'), 2, 10) + CONV(BINARY('1111111011'), 2, 10) - 1023);
女巫会回馈101011