Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Mysql选择具有最小和最大数据的行中的间隙_Php_Mysql - Fatal编程技术网

Php Mysql选择具有最小和最大数据的行中的间隙

Php Mysql选择具有最小和最大数据的行中的间隙,php,mysql,Php,Mysql,我有一个带有最小值和最大值列的表,其中可能有重叠的数据 范例 +--------+--------+ | Minval | Maxval | +--------+--------+ | 0000 | 1000 | | 1500 | 8999 | | 0100 | 0200 | | 5000 | 6999 | +--------+--------+ 最小值和最大值的可能范围为0000-9999 我正在寻找一种方法来找出数据中的漏洞。根据上述数据,差距将为1001-

我有一个带有最小值和最大值列的表,其中可能有重叠的数据

范例

+--------+--------+
| Minval | Maxval |
+--------+--------+
|   0000 |   1000 |
|   1500 |   8999 |
|   0100 |   0200 |
|   5000 |   6999 |
+--------+--------+
最小值和最大值的可能范围为0000-9999

我正在寻找一种方法来找出数据中的漏洞。根据上述数据,差距将为1001-1499和9000-9999


我正在使用php和mysql。

您当然需要php代码

CREATE TABLE TEMP_TABLE (NUMBER_VALUE INT);

INSERT INTO TEMP_TABLE VALUES (1,2,3,....9999); 
可以使用php循环执行此操作,也可以创建一个常量查询并重用它

然后对主表中的每一行执行

DELETE FROM TEMP_TABLE WHERE NUMBER_VALUE BETWEEN MINVAL AND MAXVAL;

一旦删除,你将留下的差距,但所有的数字。然后,您可以循环使用这些函数以在PHP中存储最小值和最大值。您当然需要一个PHP代码

CREATE TABLE TEMP_TABLE (NUMBER_VALUE INT);

INSERT INTO TEMP_TABLE VALUES (1,2,3,....9999); 
可以使用php循环执行此操作,也可以创建一个常量查询并重用它

然后对主表中的每一行执行

DELETE FROM TEMP_TABLE WHERE NUMBER_VALUE BETWEEN MINVAL AND MAXVAL;

一旦删除,你将留下的差距,但所有的数字。然后,您可以循环使用这些函数以在PHP中存储最小值和最大值,而不需要PHP代码。您可以在SQL中执行此操作

间隙将从大于最大值的一个开始,到小于最小值的一个结束。然后,您只需查看某个特定记录是否参与了间隙

select t.*,
       t.maxval+1 as gapStart,
       (select min(t2.minval) - 1
        from t t2
        where t2.minval > t.maxval
       ) as gapEnd
from t
where not exists (select 1
                  from t t2
                  where t.maxval + 1 between t2.minval and t2.maxval
                 )

您不需要php代码。您可以在SQL中执行此操作

间隙将从大于最大值的一个开始,到小于最小值的一个结束。然后,您只需查看某个特定记录是否参与了间隙

select t.*,
       t.maxval+1 as gapStart,
       (select min(t2.minval) - 1
        from t t2
        where t2.minval > t.maxval
       ) as gapEnd
from t
where not exists (select 1
                  from t t2
                  where t.maxval + 1 between t2.minval and t2.maxval
                 )

结果可以通过MySQL查询返回,无需脚本

SELECT CONCAT(LPAD(r.lo,4,'0'),'-',LPAD(r.hi,4,'0')) AS gap
     , r.lo
     , r.hi
--   , d.minval IS NULL AS gap
--   , d.*
  FROM ( SELECT rl.lo, rh.hi
           FROM (SELECT 0000 AS lo UNION 
                 SELECT rlo.maxval+1
                   FROM example1 rlo
                  WHERE rlo.maxval < 9999
                 ) rl
            JOIN (SELECT 9999 AS hi UNION
                  SELECT rhi.minval-1
                    FROM example1 rhi
                   WHERE rhi.minval > 0000
                 ) rh
              ON rh.hi >= rl.lo
           GROUP BY rl.lo, rh.hi
       ) r
  LEFT
  JOIN example1 d
    ON r.lo BETWEEN d.minval+0 AND d.maxval+0
    OR r.hi BETWEEN d.minval+0 AND d.maxval+0
    OR d.minval+0 BETWEEN r.lo AND r.hi
    OR d.maxval+0 BETWEEN r.lo AND r.hi
 WHERE d.minval IS NULL
 ORDER
    BY r.lo, r.hi
--   , d.minval, d.maxval
编辑

我刚刚注意到OP注释中的数据类型是CHAR(4),我假设它是整数类型,很可能是
INT(4)ZEROFILL
。上面的查询也可以处理字符类型,但我们需要确保字符转换为整数,最简单的方法是向列引用中添加“+0”,并进行调整和测试

CREATE TABLE `example1` (minval CHAR(4), maxval CHAR(4));
INSERT INTO `example1` VALUES ('0055','1000')
  ,('1500','8999'),('0100','0200'),('5000','6999');

结果可以通过MySQL查询返回,无需脚本

SELECT CONCAT(LPAD(r.lo,4,'0'),'-',LPAD(r.hi,4,'0')) AS gap
     , r.lo
     , r.hi
--   , d.minval IS NULL AS gap
--   , d.*
  FROM ( SELECT rl.lo, rh.hi
           FROM (SELECT 0000 AS lo UNION 
                 SELECT rlo.maxval+1
                   FROM example1 rlo
                  WHERE rlo.maxval < 9999
                 ) rl
            JOIN (SELECT 9999 AS hi UNION
                  SELECT rhi.minval-1
                    FROM example1 rhi
                   WHERE rhi.minval > 0000
                 ) rh
              ON rh.hi >= rl.lo
           GROUP BY rl.lo, rh.hi
       ) r
  LEFT
  JOIN example1 d
    ON r.lo BETWEEN d.minval+0 AND d.maxval+0
    OR r.hi BETWEEN d.minval+0 AND d.maxval+0
    OR d.minval+0 BETWEEN r.lo AND r.hi
    OR d.maxval+0 BETWEEN r.lo AND r.hi
 WHERE d.minval IS NULL
 ORDER
    BY r.lo, r.hi
--   , d.minval, d.maxval
编辑

我刚刚注意到OP注释中的数据类型是CHAR(4),我假设它是整数类型,很可能是
INT(4)ZEROFILL
。上面的查询也可以处理字符类型,但我们需要确保字符转换为整数,最简单的方法是向列引用中添加“+0”,并进行调整和测试

CREATE TABLE `example1` (minval CHAR(4), maxval CHAR(4));
INSERT INTO `example1` VALUES ('0055','1000')
  ,('1500','8999'),('0100','0200'),('5000','6999');


最小和最大varchar的数据类型是什么?为什么不是int?为什么有前导零?为什么在字符列中存储整数值?最小和最大varchar的数据类型是什么?为什么不是int?为什么会有前导零?为什么要在字符列中存储整数值?这真的是临时表的最有效方法吗…?将值列表转换回某个范围的最佳方法是什么,例如
'1001-1499'
,而不是将间隙报告为
'1001-1001'
'1002-1002'
'1003-1003'
,等。@James-我不认为这是最有效的,但它解决了这个问题fully@spencer7593PHP循环,该循环运行并检查其旁边是否有值,如果没有,则将其报告为间隙开始并继续,直到出现新的连续值,虽然被接受的答案也可以很好地调整,但这是处理这个真正临时表的最有效方法…?将值列表转换回某个范围的最佳方法是什么,例如
'1001-1499'
,而不是将间隙报告为
'1001-1001'
'1002-1002'
'1003-1003'
,等。@James-我不认为这是最有效的,但它解决了这个问题fully@spencer7593PHP循环,它运行并检查它旁边是否有值,如果没有,则报告它作为间隔开始并继续,直到新的连续值,而接受的答案也可以微调,这是一个赢家。谢谢你。我同意resultset可以只使用MySQL返回。但有一个边缘情况,我认为这无法处理:从
0000开始的间隙。(例如,如果该
(00001000)
行更改为
(00551000)
)。我也采取了类似的方法。我生成了所有可能间隙的集合(我们知道任何间隙都将在0000、9999、minval-1或maxval+1开始和结束。很容易得到所有“可能间隙”的整个集合(忽略minval>maxval的交叉连接,我必须在0000和9999中并集)。在我的查询中不起作用的是消除所有非实际间隙的行。@Chinaski…请注意,如果您想处理这两种边缘情况,可以使用
union all
语句,与最小的minval和最大的maxval进行比较。这是一个赢家。谢谢。+1。我同意返回结果集时只需MySQL。但是有一个边缘情况,我不认为这可以处理:一个从
0000
开始的间隙(例如,如果
(00001000)
行被更改为
(00551000)
),我采用了类似的方法。我生成了所有可能的间隙集(我们知道任何间隙都将在0000、9999、minval-1或maxval+1处开始和结束。很容易得到所有“可能间隙”的整个集合(忽略minval>maxval的交叉连接,我必须在0000和9999处并集)。在我的查询中不起作用的是消除所有非实际间隙的行。@Chinaski…请注意,如果您想处理这两种边缘情况,可以使用
union all
语句,与最小的minval和最大的maxval进行比较。这更完整。也感谢您的解释。我仍在尝试分析怎么样。@Chinaski:诀窍在于查询
r
(您可以单独运行)来生成每个可能的范围。
rl
获取每个可能的间隙的“min”,而
rh
获取每个可能的间隙的“max”。我们进行连接,并获取每个可能的间隙。(只有当hi小于lo时,lo和hi的组合才不会成为间隙。下一个技巧是“反连接”…找出所有这些可能的间隙中哪些不是真正的间隙,因为它们