SQL 查询到 mysql(子查询不识别外部 table)

SQL query to mysql (Subquery does not recognize outer table)

我知道 mysql 无法识别子查询中的外部 table,但遗憾的是我不知道如何解决这个问题。

首先是table结构,我有三个tables(m到n):

表 1: 舞蹈

 TID | Name_Of_The_Dance   
 12  | Heute Tanz ich

表二: 舞者

TAID | Name_Of_Dancer
 1 | Alex Womitsch  
 2 | Julian Berger

表 3(引用 table): dance2dancer

TID | TAID   
 12 | 213   
 12 | 345 

我要实现什么(输出):

TID | AllDancerWhoDance  
12 |  213---,345---,0---,0---,0---,0---,0---,0---,0---,0--- 

每个输出都应该有舞蹈TID和所有跳这个舞的舞者。但是AllDancerWhoDance应该填“0---”,当我们有少于10个dancer时。当这个舞蹈中有超过 10 个舞者时,查询应将字符串减少到最多 10 个舞者。

更多需要理解的例子: 一个有 4 个舞者的舞蹈应该填满 6 个零:

9 | 213---,345---,111---,459---,0---,0---,0---,0---,0---,0---   

我们是否有超过 10 名舞者的舞蹈查询应将其减少到 10:

9 | 213---,345---,111---,459---,333---,444---,445---,222---,192---,490--- (NO more zeros or dancer TAIDs)

这是我的查询:

select dancer.tid, 
    IF(count(dancer.taid) <= 10, 
        CONCAT_WS("",GROUP_CONCAT(dancer.taid,"&&&"), REPEAT(";0",10-count(dancer.taid)))
      , (SELECT GROUP_CONCAT(a.taid,"&&&") from (SELECT ttt.taid from dance2dancer ttt inner join dance taenz on ttt.tid = taenz.tid where ttt.tid = dance.tid LIMIT 10) as a)
      ) AS "AllDancerWhoDance"
from dance inner join dance2dancer tt on dance.tid = tt.tid inner join dancer on tt.taid = dancer.taid group by dance.tid

我认为它会起作用,但问题是子查询不查看外部 table 并且 "where" 子句不起作用:
其中 ttt.tid = dance.tid

现在我的问题是:
如何在 mysql 中实现此 sql 查询?

谢谢

//更新
因为很多人询问前端代码以及为什么我需要这个查询:我们有一个 22 年的软件,需要这种格式的数据。它是由一家不复存在的公司编写的,我们没有该程序的任何源代码。我们已经将数据库和网站更改为这个新的数据模型 (m:n),但是旧程序仍然需要旧格式的数据。因此我需要这个奇怪的查询。 是的,我们也在开发一个新程序。

要让 10 名舞者参加给定的舞蹈,请执行以下操作:

select D.Name_Of_Dancer 
from  dancer DR, dance2dancer DD
where DD.taid = DR.taid 
groupby DD.tid
Limit 10

您还可以添加 Desc 或 ASC 来对舞者列表的列表进行排序并提取前 10 位舞者。

但是要在一个列表中获得至少 10 个舞者,即使它不存在。 mysql 不可能。我的意思是告诉我前端的代码你是如何处理的,我们能做的就是计算结果的数量。如果结果是 4,我们可以简单地使用一个循环来创建 6 个其他条目以获得总共 10 个舞者。但我不建议从 mysql 端处理它们。这是一个不好的做法。

错误的原因是您无法从派生的 table(您的 from (...) as a)内部访问外部列。为此,您必须编写类似 (...) as a where a.tid = dancer.tid 的内容,因此您将 where 放在派生的 table 之外;但是您显然必须以某种方式重写 a 以将 tid 作为列。

在你的情况下,修复你的代码会更复杂,所以我给你写了一个(更简单的)新代码:

select tid,
  CONCAT_WS("",
  (SELECT GROUP_CONCAT(d2d2.taid,"---") 
   from dance2dancer d2d2
   where d2d2.tid = d2d.tid 
   group by d2d2.tid limit 10),
  REPEAT(",0---",10-count(distinct d2d.taid))
  ) as `AllDancerWhoDance`
from dance2dancer d2d
group by d2d.tid

还有一个警告:这种查询(在列中使用 group_concat 或 concat)仅在最后一步用于格式化要显示的数据。如果您打算在另一个查询中使用它,例如类似 select * from dancer where INSTR('213---,345---,111---', taid) > 0 的东西,请不要,只需重写即可。

更新 不使用 limit 10:

尽管 limit 10 应该与 group_concat 一起使用(它对我有用),如果它对你不起作用,你当然可以只连接所有内容然后取前 10 个条目之后的连接字符串。它实际上会简化查询,因为您不再需要子查询(首先只有 limit),但可能会生成一个大的临时字符串(在 substring_index 之前)如果你和很多舞者一起跳舞。

select tid,
  SUBSTRING_INDEX(CONCAT_WS("",
  GROUP_CONCAT(d2d.taid,"---"),
  REPEAT(",0---",10-count(distinct d2d.taid)),
  ','
  ), ',',10) as `AllDancerWhoDance`
from dance2dancer d2d
group by d2d.tid;

或者预先计算行号,每个 tid 只取前 10 行:

select d2d.tid, CONCAT_WS("",
  GROUP_CONCAT(d2d.taid,"---"),
  REPEAT(",0---",10-d2d.cnt)
  ) as `AllDancerWhoDance`
from 
(select tid, taid, 
      (select count(*) 
       from dance2dancer d2d4
       where d2d4.tid = d2d3.tid
       and d2d4.taid <= d2d3.taid
      ) as rownum,
      (select count(*) 
       from dance2dancer d2d4
       where d2d4.tid = d2d3.tid
      ) as cnt
      from dance2dancer d2d3
) as d2d
where d2d.rownum <= 10
group by d2d.tid;