Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.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
Mysql 如何在SQL中标记不同的值范围_Mysql_Sql_Database - Fatal编程技术网

Mysql 如何在SQL中标记不同的值范围

Mysql 如何在SQL中标记不同的值范围,mysql,sql,database,Mysql,Sql,Database,Solved显示我有一张桌子: + ---+-----+------+ | id | Low | High | + ---+-----+------+ | 1 | 3 | 10 | | 1 | 2 | 9 | | 1 | 11 | 14 | | 2 | 3 | 10 | + ---+-----+------+ 如何标记具有相同id且与int1,2,3…重叠值范围的项目,。。。?在这种情况下,带有标记的新表将是: + ---+-----+------+---

Solved显示我有一张桌子:

+ ---+-----+------+ | id | Low | High | + ---+-----+------+ | 1 | 3 | 10 | | 1 | 2 | 9 | | 1 | 11 | 14 | | 2 | 3 | 10 | + ---+-----+------+ 如何标记具有相同id且与int1,2,3…重叠值范围的项目,。。。?在这种情况下,带有标记的新表将是:

+ ---+-----+------+-----+ | id | Low | High | tag | + ---+-----+------+-----+ | 1 | 3 | 10 | 1 | | 1 | 2 | 9 | 1 | | 1 | 11 | 14 | 2 | | 2 | 3 | 10 | 1 | + ---+-----+------+-----+ 由于行2和行1具有相同的id,并且它们的值范围有重叠,因此它们的标记都是1,对于行3,因为其值范围Low、high不同于行1和行2,所以它们的标记是2。对于第4行,由于它与上面3行具有不同的id,因此它的标记将为1。 基本逻辑是:在同一个id中,我们只需要区分所有类型的值范围,并给它们标记1,2,3。。。。我们定义了两个项目的值范围,如果它们有重叠,则应分配相同的标记。所以值范围3,9,3,10,2,9都是标记1,因为它们有重叠。对于11、14,由于它是一个完全不同的值范围,没有与任何其他值重叠,因此它被分配了一个新的标记,标记分配是针对每个id进行的。
我很困惑,请帮助。

我不确定是否有其他数据示例,但根据我所得到的,这将起作用:

select id, low, high,
DENSE_RANK() over (partition by id order by id, res desc) as tag
from
(select id, low, high, (high-low) as res
from test) a
您可以使用a来执行此操作

WITH RECURSIVE cte AS
(
    SELECT id, Low, High, Low AS MinLow
    FROM YourTable
    UNION ALL
    SELECT cte.id, cte.Low, cte.High, yt.Low
    FROM cte
    INNER JOIN YourTable yt ON yt.id = cte.id AND cte.MinLow > yt.Low AND cte.MinLow <= yt.High
),
g AS
(
    SELECT id, Low, High, MIN(MinLow) AS MinLow
    FROM cte
    GROUP BY id, Low, High
)
SELECT id, Low, High, DENSE_RANK() OVER (PARTITION by id ORDER BY id, MinLow ASC) AS tag
FROM g

您希望按ID对范围进行群集。假设ID 1的数据为

+ ---+-----+------+ | id | Low | High | + ---+-----+------+ | 1 | 2 | 7 | | 1 | 3 | 4 | | 1 | 7 | 8 | | 1 | 7 | 10 | | 1 | 12 | 13 | | 1 | 13 | 20 | | 1 | 20 | 24 | + ---+-----+------+ 我们有两个集群:2-10,12-24。仅仅查看另一行(比如前一行)来确定它们是否在同一集群中是不够的。3-4和7-8乍一看似乎不相关,但它们属于同一个集群,因为它们都与2-7重叠

我在这里看到了一个迭代过程,我们按ID和Low对行进行排序,并在继续操作时保持最大范围值:

+ ---+-----+------+---------+----------------------------------+ | id | Low | High | Highest | Cluster | + ---+-----+------+---------+----------------------------------+ | 1 | 2 | 7 | 7 | 1 (start with #1) | | 1 | 3 | 4 | 7 | 1 (3 <= 7) | | 1 | 7 | 8 | 8 | 1 (7 <= 7) | | 1 | 7 | 10 | 10 | 1 (7 <= 8) | | 1 | 12 | 13 | 13 | 2 (next number, because 12 > 10) | | 1 | 13 | 20 | 20 | 2 (13 <= 13) | | 1 | 20 | 24 | 24 | 2 (20 <= 20 | + ---+-----+------+---------+----------------------------------+ 对于迭代过程,我们需要SQL中的递归查询:

with recursive numbered as
(
  select t.*, row_number() over (partition by id order by low) as rn
  from mytable t
)
, cte (id, rn, low, high, highest, tag) as
(
  select id, rn, low, high, high, 1 from numbered where rn = 1
  union all
  select 
    n.id, n.rn, n.low, n.high, 
    case when n.low <= c.highest then greatest(n.high, c.highest) else n.high end,
    case when n.low <= c.highest then c.tag else c.tag + 1 end
  from cte c
  join numbered n on n.id = c.id and n.rn = c.rn + 1
)
select id, low, high, tag
from cte
order by id, low, high;

演示:

另一种方法是简单地从高减去低,然后输出该数字,您将使用该数字做什么?我只是尝试为这些具有重叠值范围的项目分配一个标记,标签分配将针对不同的id进行。标签号没有特殊用途。这样您就可以按从大到小的范围进行排序了吗?如果是这样的话,我可以为你写一个解决方案。如果8,12以后加上呢?然后突然,标记1和2需要合并成一个标记?@AlexZ我看到你改变了接受的答案,你找到了我的解决方案不起作用的数据集吗?或者您只是更喜欢另一个答案提供的解释和/或语法?High VBoka,非常感谢您的回答,但这里有一个问题,因此如果我在第二行下的测试值1、3、9中插入另一行insert,这一行也应该有标记1,因为它与第1行和第2行重叠,但它被标记为2。在这种情况下,我想给出一个新的标记,当且仅当该行有一个全新的值范围时,这意味着它没有与具有相同id的所有其他行的值范围重叠。我已经更改了我的查询,我在内部查询中添加了order by id,但我很困惑。你怎么说1,3,9会有标签1?差别是69-3,所以应该是标签2,对吗?我在分析,我没有听你说的。你说过标签是这样做的:ID,然后是rangelow,high。1,3,9与1,3,10的范围不同。或者我对这个范围的理解是错误的?我理解。谢谢有什么想法吗?非常感谢你。