MySQL在两列序列中找到差距

时间:2019-05-29 17:30:53

标签: mysql

我已经搜索并尝试在此处修改其他答案以寻求解决方案,但是我无法提出任何可行的方法。

我有一个具有两列序列的表。不幸的是,第一列是一个字符串,它代表一个十六进制值,例如。 0x0010。第二列是另一个计数器,范围从0到15(含)。

我正在寻找每个十六进制空间中从0x0000到0xFFFF以及从0-15的间隙。一些十六进制空格可以完全为空,在这种情况下,查询或过程将报告所有0-15均为空白。

例如,给定:

<a href='/tab-1'>Tab 1</Link>
<a href='/tab-2' class="red-text">Tab 2</Link>
<a href='/tab-3' >Tab 3</Link>

并且仅从0x0到0x3进行搜索,所以我会期望像这样:

id    hex_counter    integer_counter
1          0x0000                  0
2          0x0000                  1
3          0x0000                  5
4          0x0001                 10
5          0x0003                  7

或者与同一组中的每个数字都位于其自己的行中。

我尝试将其放在存储过程中,如下所示:

hex_counter    gaps
0x0000         2-4
0x0000         6-15
0x0001         0-9
0x0001         11-15
0x0002         0-15
0x0003         0-6
0x0003         8-15  

这将返回不正确的信息,例如负数等。我将在python中实现一些功能,该功能将为每个十六进制值发送查询,但是这将导致大约65535个查询,因此我想避免这种情况可能。

谢谢!

1 个答案:

答案 0 :(得分:0)

仅适用于8.0之前的版本...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,hex_counter CHAR(6) NOT NULL
,integer_counter INT NOT NULL
);

INSERT INTO my_table VALUES
(1,'0x0000', 0),
(2,'0x0000', 1),
(3,'0x0000', 5),
(4,'0x0001',10),
(5,'0x0003', 7);

DROP TABLE IF EXISTS ints;

CREATE TABLE ints (i INT NOT NULL PRIMARY KEY);

INSERT INTO ints VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

SELECT hex_counter
     , MIN(int_counter) range_start
     , MAX(int_counter) range_end 
  FROM 
     ( SELECT hex_counter
            , int_counter
            , CASE WHEN @prev=j THEN @k:=@k ELSE @k:=@k+1 END k
            , @prev:=j b
         FROM 
            ( SELECT UNHEX(HEX('0x0000')+h.i) hex_counter
                   , (i2.i*10)+i1.i int_counter
                   , COALESCE(x.integer_counter = (i2.i*10)+i1.i,0) j
                FROM ints h
                JOIN ints i1
                JOIN ints i2
                LEFT
                JOIN my_table x
                  ON x.hex_counter = UNHEX(HEX('0x0000')+h.i)
                 AND x.integer_counter = (i2.i*10)+i1.i
                JOIN (SELECT @j:=0) vars
               WHERE h.i <=3
                 AND (i2.i*10)+i1.i <= 15
               ORDER 
                  BY hex_counter
                   , int_counter
            ) a
         JOIN (SELECT @prev:=null,@k:=0) vars
        ORDER 
           BY hex_counter
            , int_counter
      ) n
  WHERE b = 0
  GROUP 
     BY hex_counter, k;

+-------------+-------------+-----------+
| hex_counter | range_start | range_end |
+-------------+-------------+-----------+
| 0x0000      |           2 |         4 |
| 0x0000      |           6 |        15 |
| 0x0001      |           0 |         9 |
| 0x0001      |          11 |        15 |
| 0x0002      |           0 |        15 |
| 0x0003      |           0 |         6 |
| 0x0003      |           8 |        15 |
+-------------+-------------+-----------+