如何在MySQL中选择一组条件的第一个匹配项
我有一张这样的桌子:如何在MySQL中选择一组条件的第一个匹配项,mysql,sql,database,Mysql,Sql,Database,我有一张这样的桌子: MyTable ------------------------------- | ID | from | to | ------------------------------- | 1 | U_002 | C_005 | | 2 | U_015 | C_004 | | 3 | C_005 | U_011 | | 4 | U_008 | C_001 | | 5
MyTable
-------------------------------
| ID | from | to |
-------------------------------
| 1 | U_002 | C_005 |
| 2 | U_015 | C_004 |
| 3 | C_005 | U_011 |
| 4 | U_008 | C_001 |
| 5 | U_007 | C_005 |
| 6 | U_001 | C_005 |
| 7 | C_004 | U_015 |
| 8 | U_002 | C_002 |
| 9 | U_001 | C_009 |
| 10 | U_010 | C_005 |
| 11 | C_005 | U_001 |
| 12 | U_004 | C_003 |
| 13 | U_005 | C_005 |
| 14 | U_010 | C_001 |
| 15 | C_005 | U_001 |
-------------------------------
ID
,是表的唯一增量键
目标是:
- 通过给出一个值(例如:
,C_005
,U_001
,等等),获得这两个条件的第一个匹配:C_010
从较高的((from==value)|(to==value))
ID开始
C_004
和U_015
有两个条目(C_004->U_015
和U_015->C_004
)。这应该只返回一个。
由于我们希望从更高的Id
开始,这意味着它将只返回7 | C|U 004 | U_015
让我们举一个例子:
- 值=
C_005
15 | C_005 | U_001
13 | U_005 | C_005
10 | U_010 | C_005
5 | U_007 | C_005
3 | C_005 | U_011
1 | U_002 | C_005
我们的想法是获得两个值的“last”(因为我们从更高的
Id
)重合
正如我所说,两个值可以有多个重合,但我只想得到“最后”一个(更高的Id
)。使用max()
您的数据被弄乱了,因为您有重复的数据,并且可能还有周期。啊。你应该修正数据 但您仍然可以使用递归CTE执行您想要的操作:
with recursive cte as (
select id, f, t, 1 as lev, cast(t as char(1000)) as visited
from t
where f in ('C_005') /*, 'U_001', 'C_010') */
union all
select t.id, t.f, t.t, lev + 1, concat_ws(',', cte.visited, t.f)
from cte join
t
on cte.f = t.t
where cte.visited not like concat('%', t.f, '%')
)
select distinct id, f, t
from cte
order by id desc;
是一个dbfiddle。CTE中的ROW_NUMBER()。您写入“获取第一个匹配”,但预期结果有6行。您想要一行还是全部?为每组两个条件获取第一个匹配。第一个匹配基于什么?因为在您的数据集中,第一个匹配将是ID=1,并且输出将仅为1行。但您需要6行,其中value='C_005'。因此,一个简单的
from='C_005'或to='C_005'
应该可以工作。为什么需要分组?其思想是创建“组”,其中from
或to
等于值。然后,返回每个组的第一个匹配项(这就是为什么有6个结果)。我们使用ID,可以从更高的起点开始。PS:我不确定这是不是解决方案,这是我的猜测。谢谢!我必须多看一点才能理解它(mysql非常新)。想象一下这是一个“消息”列表(我没有添加其他列)。它有“重复项”,因为它在两个“值”之间可以有多条消息。我们一直在研究它,有了这个,它不是“过滤”的,只是第一个匹配项没有?它也给了我11分和6分。@SpykeRel04D。当然您可以指定要在'C_005'
上进行筛选,这些也在集合中。如果您只想在id=3
上进行筛选,那么更改第一个where
子句。这不是关于id=3
“获取这两个条件的第一个匹配:((from==value)|(to==value))从更高的id开始。因此,我们的想法是只得到每个“组”的第一个“结果”,而不需要重复数据。
with recursive cte as (
select id, f, t, 1 as lev, cast(t as char(1000)) as visited
from t
where f in ('C_005') /*, 'U_001', 'C_010') */
union all
select t.id, t.f, t.t, lev + 1, concat_ws(',', cte.visited, t.f)
from cte join
t
on cte.f = t.t
where cte.visited not like concat('%', t.f, '%')
)
select distinct id, f, t
from cte
order by id desc;