sql >> データベース >  >> RDS >> Mysql

SQLクエリ複数のテーブル、複数の結合、およびコンマ区切りのリストを含む列フィールド

    テーブル構造を実際に変更できない場合、おそらく最善の方法は、古いリストハックの1つです。

    • JOINを使用する FIND_IN_SET(value、commaSeparatedString)

      SELECT n.Host, c.Name AS ControlName, s.Name AS ServiceName FROM node n LEFT JOIN control c ON c.controlID = n.controlID LEFT JOIN service s ON FIND_IN_SET(s.serviceID, n.serviceId) ORDER BY n.host, s.Name ;

    • LIKEを使用する ノードリスト内の特定のserviceID値の存在を検出する

      SELECT n.Host, c.Name AS ControlName, s.Name AS ServiceName FROM node n LEFT JOIN control c ON c.controlID = n.controlID LEFT JOIN service s ON CONCAT(',', n.serviceID,',') LIKE CONCAT('%,', s.serviceID,',%') ORDER BY n.host, s.Name ;

    SQLFiddle

    ただし、すでに述べたように、列は実際には正規化する必要があります。上記の方法は小さなデータセットでも機能するはずですが、「リスト」を操作する際の通常の問題に悩まされています。どちらの方法もインデックスにあまり適しておらず、その結果、適切にスケーリングできません。また、両方とも文字列比較を実行します。したがって、わずかな違いにより、マッチングが失敗する可能性があります。例:1,4 1,(space)4に対して、2つのserviceIDに一致します または1,4.0 1つだけに一致します。

    コメントに基づいて更新:

    2回目の読み取りでは、上記があなたが尋ねている正確な質問に答えるかどうかはわかりませんが、それは作業するための良い基盤を提供するはずです...

    CSVリストが不要になった場合は、上記のクエリの1つを使用して、通常どおり個々のクエリ列を出力してください。結果は、行ごとに1つのサービス名になります。つまり:

       server1 | Control Name One | Service Name 200
       server1 | Control Name One | Service Name 50
       ..
    

    それ以外の場合、コンマ区切りの値を保持する必要がある場合、1つの可能性は<cfoutput group="..">を使用することです。 クエリ結果。結果は最初に「ホスト」順に並べられるため、以下のコードのようになります。 NB: 「グループ」が正しく機能するには、結果をHostで並べ替える必要があります また、複数のcfoutputを使用する必要があります 以下に示すタグ。

     <cfoutput query="..." group="Host"> 
        #Host# |
        #ControlName# |
        <cfoutput>
          #ServiceName#,
        </cfoutput>
        <br>
     </cfoutput>
    

    結果は次のようになります。

    server1 | Control Name One | Service Name 200, Service Name 50, Service Name Four, Service Name One, Service Name Three, Service Name Two, 
    server2 | Control Name Two | Service Name 200, Service Name Four, Service Name Three, Service Name Two, 
    server3 | Control Name Two | Service Name 200, Service Name 50, Service Name Four, Service Name One, Service Name Three, Service Name Two, 
    server4 | Control Name Three | Service Name 200, Service Name 50, Service Name One, Service Name Two, 
    server5 | Control Name Three | Service Name Four, Service Name One, 
    


    更新2:

    cfoutput groupのより簡単な代替手段があることを忘れました MySQLの場合: GROUP_CONCAT

    <cfquery name="qry" datasource="MySQL5">
       SELECT n.Host, c.Name AS ControlName, GROUP_CONCAT(s.Name) AS ServiceNameList 
       FROM node n 
            LEFT JOIN control c ON c.controlID = n.controlID 
            LEFT JOIN service s ON FIND_IN_SET(s.serviceID, n.serviceId) 
       GROUP BY n.Host, c.Name
       ORDER BY n.host
    </cfquery>
    



    1. SQLiteFTS3テーブルの行IDを取得します

    2. SQLServer2017でデータベースをバックアップする

    3. 存在する場合は選択し、そうでない場合は挿入しますか?

    4. MySQL-列にNULL値を挿入できませんが、デフォルト値を指定していますか?