MariaDB 查询使用 IN 和 LIMIT 按行

MariaDB Query using IN with LIMIT by row

我在我的一个子查询中尝试使用 LIMIT 时遇到了一些困难,我 运行 进入了错误

MariaDB doesn't yet support 'LIMIT in subquery'

在一个类似于我在 PostgreSQL 中所做的查询中,以便为每个具有 child

的 parent 获得 3 child 个结果
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 完成的工作示例。它只返回两条 parent 条记录,并且对于每个 parent 它只返回 2 child 条记录

请用文字说明想要的结果。

同时,看看这是否能满足您的需求:

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_;听起来很像 "parent",但显然 ch_ 表示 "parent".

_id_idno有什么区别?

在 parent-child(分层)关系的许多实现中,两者都在同一个 table 中。 table 有 PRIMARY KEY(id) 和一个名为 parent_id 的列然后 "selfjoin" 用于连接父子关系。

如果您同时为 parentchild 提供 SHOW CREATE TABLE,也可能会有帮助。

原始查询的解决方法:

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;

保留原始的 sub-query 操作以从 child table 中提取 ch_id LIMIT 3 但是添加 parent table 在加入。然后执行另一个操作以获得 sub-query 结果,然后将其用于 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;

老实说,我担心这在大数据中表现不佳,但我一直在学习新东西和我最近才发现的一些功能。

根据您的 fiddle,我注意到您每 parent 只取前 3 ch_id。因此,这个SUBSTRING_INDEX(GROUP_CONCAT(ch_id ORDER BY ch_id ASC SEPARATOR ' '),' ',3) chidGROUP_CONCAT 水平显示数据,SUBSTRING_INDEX 获取程序集中的前 3 个 ch_id。通常 group_concat 将 return 这样的值; 1,2,3和substring_index只能识别以[space]('')分隔的第一个,第二个和so-on值。这就是我添加 SEPARATOR ' '.

的原因

然后我在外部查询中使用 SUBSTRING_INDEX 两次来定义 fe,其中 SUBSTRING_INDEX(chid,' ',1) 获取第一个值, SUBSTRING_INDEX(chid,' ',-1) 获取列中的最后一个值。然后我将它与原始查询结合起来并添加了 BETWEEN f and e.