如何在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;