MariaDB 查询使用 IN 和 LIMIT by row
Posted
技术标签:
【中文标题】MariaDB 查询使用 IN 和 LIMIT by row【英文标题】:MariaDB Query using IN with LIMIT by row 【发布时间】:2019-09-15 23:30:18 【问题描述】:我在尝试在我的一个子查询中使用 LIMIT 时遇到了一些困难,我遇到了错误
MariaDB doesn't yet support 'LIMIT in subquery'
关于一个类似于我在 PostgreSQL 中所做的查询,以便为每个有孩子的父母获得 3 个孩子结果
select * from parent
join child on child.ch_pa_id = parent.pa_id
and child.ch_id in (
select child.ch_id from child
where child.ch_id = parent.pa_id
limit 3
)
order by parent.pa_id;
我看到这里有一个关于同一件事的问题
mysql - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery
这个问题有答案,但我无法让它满足我的需要,主要是因为我需要通过连接逐行完成,我尝试将同样的事情应用于我的查询,但我不确定如何保持连接工作
select * from parent as p
join (
select * from child
where child.ch_pa_idno = p.pa_idno # this line breaks it
limit 3
) as c on c.ch_pa_id = p.pa_id
order by p.pa_id;
p.pa_idno 是一个未知列会给出错误,我确定我是个白痴,这里有明显的问题
示例
这是一个使用 PostgreSQL http://sqlfiddle.com/#!17/4ed4d/2 完成的工作示例。它只返回两个父记录,对于每个父记录,它只返回 2 个子记录
【问题讨论】:
没有ORDER BY
的LIMIT
可能会导致随机结果。
true 但在这种情况下顺序并不重要,因为它只是一个示例
【参考方案1】:
原始查询的解决方法:
SELECT * FROM parent
JOIN child ON child.ch_pa_id = parent.pa_id
AND child.ch_id IN
(SELECT ch_id FROM (
SELECT child.ch_id FROM child JOIN parent
WHERE child.ch_id = parent.pa_id
LIMIT 3) a
)
ORDER BY parent.pa_id;
保留原始子查询操作以从具有LIMIT 3
的子表中提取ch_id
,但是通过在联接中添加parent
表。然后执行另一个操作以获取子查询结果,然后将其用于您的IN
。
编辑: 我有一个有效的查询,但我对它的感觉很复杂:
SELECT * FROM parent
JOIN child ON parent.pa_id=child.ch_pa_id
LEFT JOIN (
SELECT ch_pa_id,SUBSTRING_INDEX(chid,' ',1) f,SUBSTRING_INDEX(chid,' ',-1) e
FROM (
SELECT ch_pa_id,
SUBSTRING_INDEX(GROUP_CONCAT(ch_id ORDER BY ch_id ASC SEPARATOR ' '),' ',3) chid
FROM child
GROUP BY ch_pa_id) a) b
ON child.ch_pa_id=b.ch_pa_id
WHERE child.ch_id
BETWEEN f AND e;
老实说,我担心这在大数据中表现不佳,但我一直在学习新东西,其中一些功能是我最近才发现的。
根据您的小提琴,我注意到您只为每个父母选择前 3 个ch_id
。因此,这个SUBSTRING_INDEX(GROUP_CONCAT(ch_id ORDER BY ch_id ASC SEPARATOR ' '),' ',3) chid
。 GROUP_CONCAT
水平显示数据,SUBSTRING_INDEX
获取程序集中的前 3 个 ch_id
。通常 group_concat 会这样返回值; 1,2,3
和 substring_index 只能识别第一个、第二个等值,以[空格]('')分隔。这就是我添加SEPARATOR ' '
的原因。
然后我在外部查询中使用SUBSTRING_INDEX
两次来定义f
和e
,其中SUBSTRING_INDEX(chid,' ',1)
获取第一个值,SUBSTRING_INDEX(chid,' ',-1)
从列中获取最后一个值。然后我将它与原始查询一起加入并添加BETWEEN f and e
。
【讨论】:
这很接近,但它只获取链接到限制 3 返回的子行的父行,而不是像我的 PostgreSQL 那样为每个父行返回 3 个子行 哇,这似乎确实有效,但是 phewww... 看起来很复杂 XD 确实如此!我仍在尝试找到一种更简单的方法,而且我是 MariaDB 的新手:D 我也是!不过,PostgreSQL 永远是我的宝贝【参考方案2】:请用文字解释想要的结果。
同时,看看这是否能满足您的需求:
SELECT p.*
FROM parent AS p
JOIN child AS c ON c.ch_pa_idno = p.pa_idno
ORDER BY p.pa_id
LIMIT 3
我被pa_
弄糊涂了;这听起来很像“父母”,但显然ch_
表示“父母”。
_id
和_idno
有什么区别?
在父子(分层)关系的许多实现中,两者都在同一个表中。该表有PRIMARY KEY(id)
和一个名为parent_id
的列,然后使用“selfjoin”连接父子节点。
如果您同时为parent
和child
提供SHOW CREATE TABLE
也可能会有所帮助。
【讨论】:
这是一个使用 PostgreSQL sqlfiddle.com/#!17/4ed4d/2 完成的工作示例,我也会将其包含在我的问题中以上是关于MariaDB 查询使用 IN 和 LIMIT by row的主要内容,如果未能解决你的问题,请参考以下文章