1

mysql がサブクエリからの外部テーブルを認識しないことは知っていますが、残念ながらこれを解決する方法がわかりません。

まずテーブル構造です。3 つのテーブル (m から n) があります。

表1: ダンス

 TID | Name_Of_The_Dance   
 12  | Heute Tanz ich

表 2: ダンサー

TAID | Name_Of_Dancer
 1 | Alex Womitsch  
 2 | Julian Berger

Table3 (参照テ​​ーブル): dance2dancer

TID | TAID   
 12 | 213   
 12 | 345 

達成したいこと (出力):

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

すべての出力には、ダンス TID と、このダンスで踊るすべてのダンサーが含まれている必要があります。ただし、ダンサーが 10 人未満の場合は、AllDancerWhoDance を「0---」で埋める必要があります。このダンスに 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

うまくいくと思いますが、問題は、サブクエリが外部テーブルを調べず、「where」句が機能しないことです:
where ttt.tid = dance.tid

そして今、私の質問:
この sql クエリを mysql で動作させるにはどうすればよいですか?

ありがとうございました

//UPDATE
多くの人がフロント エンド コードと、なぜこのクエリが必要なのかを尋ねているためです。22 年前のソフトウェアがあり、このような形式のデータが必要です。もう存在しない会社からプログラムされたものであり、このプログラムのソースコードはありません。データベースと Web サイトをこの新しいデータモデル (m:n) に変更しましたが、古いプログラムには古い形式のデータが必要です。したがって、この奇妙なクエリが必要です。はい、私たちは新しいプログラムにも取り組んでいます。

4

2 に答える 2

0

エラーの理由は、派生テーブル内から外側の列にアクセスできないためです (あなたのfrom (...) as a)。そのためには、 のように書かなければならないので、派生テーブルの外側に(...) as a where a.tid = dancer.tid置きます。しかし、明らかに、コラムとして持つようwhereに書き直す必要があります。atid

あなたの場合、コードを修正するのはより複雑になるので、(より簡単な) 新しいものを書きました:

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:

group_concatlimit 10で動作するはずですが (私にとっては動作します)、動作しない場合は、もちろんすべてを連結してから、連結された文字列の最初の 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;
于 2016-05-05T10:44:03.303 に答える