SQL查询到mysql(子查询无法识别外表)

时间:2016-05-05 08:58:38

标签: mysql sql-query-store

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

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

表1:  跳舞

TAID | Name_Of_Dancer
 1 | Alex Womitsch  
 2 | Julian Berger

表2:  舞者

TID | TAID   
 12 | 213   
 12 | 345 

表3(引用表):   dance2dancer

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

我想要实现什么(输出):

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

每个输出应该有舞蹈TID和所有在这个舞蹈中跳舞的舞者。但是当我们有不到10个舞者时,AllDancerWhoDance应该填满“0 ---”。当我们在这个舞蹈中有超过10个舞者时,查询应该将弦乐减少到最多10个舞者。

更多关于unterstand的例子: 与4位舞者一起跳舞应该填充6个零:

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

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

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

以下是我的问题:

{{1}}

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

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

谢谢

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

2 个答案:

答案 0 :(得分:0)

为一个特定的舞蹈获得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端处理它们。这是一个不好的做法。

答案 1 :(得分:0)

您的错误原因是您无法从派生表(from (...) as a)内部访问外部列。为此,您必须编写类似(...) as a where a.tid = dancer.tid的内容,以便将where放在派生表之外;但你显然必须以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),但可能会生成一个大的临时字符串(在{{1}之前)如果你和很多舞者一起跳舞。

substring_index

或预先计算一个rownumber,然后只取每个tid的前10行:

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;