【问题标题】:MySQL Get only first match of a conditions between 3 columnsMySQL 仅获取 3 列之间条件的第一个匹配项
【发布时间】:2021-02-28 20:58:51
【问题描述】:

我正在使用可以访问 MySQL 数据库的 API REST (NodeJS)。 在这个数据库中,有一个如下所示的表(我们将其命名为 Table_01):

| C_0| C_1| C_2| C_3| 
|  1 | A1 | B1 |  1 |
|  2 | A1 | B2 |  0 |
|  3 | B1 | A1 |  0 |
|  4 | A2 | B1 |  0 |
|  5 | B2 | A1 |  1 |
|  6 | B1 | A1 |  0 |
|  7 | B3 | A1 |  0 |
|  8 | A1 | B3 |  1 |
|  9 | A3 | B1 |  0 |
| 10 | A1 | B3 |  1 |
| 11 | A1 | B1 |  0 |

我的目标是为 C_1 和 C_2 中的一对值在 C_3 上获得 Value = 1 的第一个匹配项。

让我们举个例子。

我想知道在什么情况下C_1 中的A_1,有一个C_3 中的1(仅第一个匹配项)

所以,在这种情况下,结果应该是:

A1 B1 1
A1 B3 1

JSON 格式:

result = [
  {
    "C_1": "A1",
    "C_2": "B1",
    "C_3": "1",
  },
  {
    "C_1": "A1",
    "C_2": "B3",
    "C_3": "1",
  }
];

我不想收到第二次两次,因为 A1 B3 = 1 包含在表中 2 次。

我可以得到这样的结果:

db.query('SELECT * FROM `Table_01` WHERE (`C_1` = A1 AND `C_2` = '+db.escape(value)+') AND `C_3` = 1',
  (err, res) => {
    ..
  }
);

但这会给我第三个条目,其中包含重复的 A1 B3 1。

显然在这个例子中不是很重要。但是对于一个充满行的表,这对于避免非常大的响应和后置 JS 过滤器很重要。

【问题讨论】:

  • 只有在定义了(唯一)排序时才存在术语“第一次匹配”。您需要按C_0 升序排列吗?
  • C_0 是我的增量唯一。我不明白为什么这必须是“第一场比赛”的条件。谢谢
  • 想象一下无序的堆......例如砖块。这个堆中的哪块砖是第一个?
  • 好的,我明白了。我以为 SQL 是默认排序的。
  • 严格向后。

标签: javascript mysql node.js json greatest-n-per-group


【解决方案1】:

一种方法使用相关子查询进行过滤:

select t.*
from table_01 t
where t.id = (
    select min(t1.id) 
    from table_01 t1 
    where t1.c_1 = t.c_1 and t1.c_2 = t.c_2 and t1.c_3 = 1 
)

如果您运行的是 MySQL 8.0,您还可以使用窗口函数:

select *
from (
    select t.*,
        row_number() over(partition by c_1, c_2 order by id) rn
    from mytable t
    where c_3 = 1
) t
where rn = 1

【讨论】:

  • 完美运行。谢谢。关于窗口函数,它们是否比第一个更快(在性能上)?
  • 您需要根据您的实际数据进行评估。第一个解决方案将利用(c_1, c_2, c_3) 上的索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2015-11-23
  • 2011-01-22
  • 2014-05-21
相关资源
最近更新 更多