복붙노트

[SQL] 쉼표로 SQL 쿼리 여러 테이블, 여러 조인과 및 열 필드로 구분 된 목록

SQL

쉼표로 SQL 쿼리 여러 테이블, 여러 조인과 및 열 필드로 구분 된 목록

나는 세 개의 테이블 (노드, 제어, 서비스)에 가입하는 쿼리가 있습니다.

다음은 자신의 열 머리글 및 샘플 데이터입니다.

NODE TABLE  (contains over 7000 rows)
nodeID | host    | serviceID        | controlID
     1 | server1 | 1,2,3,4,9,50,200 |         1
     2 | server2 | 2,3,4,9,200      |         2
     3 | server3 | 1,2,3,4,9,50,200 |         2
     4 | server4 | 1,2,50,200       |         3
     5 | server5 | 1,4              |         3

CONTROL TABLE  (contains roughly 50 rows)
controlID | name
        1 | Control Name One
        2 | Control Name Two
        3 | Control Name Three
        4 | Control Name Four
        5 | Control Name Five

SERVICE TABLE (contains roughly 3000 rows)
serviceID | name
        1 | Service Name One
        2 | Service Name Two
        3 | Service Name Three
        4 | Service Name Four
        5 | Service Name Five
        6 | Service Name Six
       50 | Service Name 50
      200 | Service Name 200

당신이 볼 수 있듯이, 데이터베이스 테이블은 node.serviceID 열을 제외하고 정상화의 비트. 나는 전체 진심으로 node.serviceID가 정상화되어야한다고 동의 일대의 피벗 테이블이 생성되었습니다. 없음 인수가. 그러나, 나는 데이터베이스에 정보를 삽입 스크립트를 제어하지 않습니다. 난 단지 테이블에서 읽고 어떻게 내가 할 수있는 데이터를 포맷 할 수 있습니다.

그래서, 아래 내가 그 일을 수행하지만이 예상대로 node.serviceID가 service.serviceID 잘 참여하지 않는 쓴 SQL 쿼리입니다. 나는 노드 테이블에서 20 개 분야에 대한 선택하고 쿼리가 더 혼란하게하고 싶지 않아 내 마지막 쿼리에서 SELECT *를 사용하지 않는 오전 참고하시기 바랍니다. 아래는 단지 예입니다.

SELECT *
FROM node AS a
LEFT JOIN control AS b ON a.controlID = b.controlid
LEFT JOIN service AS c ON a.serviceID = c.serviceId
ORDER BY a.host

비슷한 뱉어 위의 쿼리 :

Host      Control              Services
server1   Control Name One     1,2,3,4,9,50
server2   Control Name Three   1,2,9,50
server3   Control Name Two     4
server4   Control Name Four    1,2,3,4,9
server5   Control Name Two     1,2,3,50
server6   Control Name Five    1,3,4,9,50

내가 무엇을 찾고 있어요 것은 이것이다 :

Host      Control              Services
server1   Control Name One     Service Name One,
                               Service Name Two,
                               Service Name Three,
                               Service Name Four,
                               Service Name Nine,
                               Service Name Fifty
server2   Control Name Three   Service Name One,
                               Service Name Two,
                               Service Name Nine,
                               Service Name Fifty
server3   Control Name Two     Service Name Four
server4   Control Name Four    Service Name One,
                               Service Name Two,
                               Service Name Three,
                               Service Name Four,
                               Service Name Nine

나는이 같은 문제를 가진 사람을 흐르고 stackoverflow.com을 가지고 있지만 난 단지 있지만 둘 다 함께 ID의 목록을 확장 ID와 이름 또는 누군가에 여러 테이블을 조인 중 하나를 찾을 수 있습니다.

이 사람은 듯했습니다 : 쉼표하지만 꽤 SQL 분리 ID를 사용하여.

나는 ListToArray와 CFML의 다양한 방법을 시도 ()와 인덱스로 전체를 반복 시도하지만, 아무것도 나를 위해 작동하지 않을 것이다.

내가로부터 데이터를하다가 서버는 MySQL의 5.1 내가 데이터를 포맷 jQuery를 및 ColdFusion (라일로 4.2)의 조합을 사용하고 있습니다.

정말이에 대한 답변이있을 경우 내 사과, 내가 충분히 검색하지 않았고,이 질문에 중복 만들 것이다, 그래서 이것은 유래 내 처음으로 게시합니다.

----------------- UPDATE --------------------

나는 쿼리를 시도하고 CFML은 레이에 의해 제안했다.

그래서 나는 다음을 얻을 :

서버 1 서비스 이름 하나, 서비스 이름 하나, 서비스 이름 하나, 서비스 이름 하나, 서비스 이름 하나, 서비스 이름 하나, 서비스 이름 하나, 서비스 이름 두, 서비스 이름 두, 서비스 이름 두, 서비스 이름 두, 서비스 이름 두 서비스 이름 두, 서비스 이름 세, 서비스 이름 네, 서비스 이름 네, 서비스 이름 네, 서비스 이름 네, 서비스 이름 네, 서비스 이름 네, 서비스 이름 네

즉, SQL 쿼리의 CFML과 변화 또는 무언가 조금 인 경우 나,이 시점에서 확실하지 않다. 그러나, 그것은 약속 봐 않습니다.

해결법

  1. ==============================

    1.당신이 정말로 테이블 구조를 수정할 수없는 경우, 아마 당신이 할 수있는 최선의 이전 목록 해킹 중 하나입니다 :

    당신이 정말로 테이블 구조를 수정할 수없는 경우, 아마 당신이 할 수있는 최선의 이전 목록 해킹 중 하나입니다 :

    SQLFiddle

    이미 해당 열을 언급하지만, 정말 정상화해야한다. 위의 방법은 작은 데이터 세트에 대한 작업을해야하지만, 그들은 "목록"작업의 일반적인 문제로 고통 받고 있습니다. 어느 방법은 매우 지수 친절, 결과적으로 잘 확장되지 않습니다. 또한, 두 문자열 비교를 수행합니다. 그래서 사소한 차이는 매칭이 실패 할 수 있습니다. 예를 들어, 1,4 1 (공간) 4 1,4.0 반면 하나와 일치하는 것이며,이 서비스 id 년대 일치합니다.

    의견에 따라 업데이트 :

    두 번째 읽기에, 나는 당신이 요구하는 위의 대답 정확한 질문을 아니지만, 그것은 함께 작동하도록 좋은 기반을 제공해야한다 ...

    더 이상 CSV 목록을하지 않으려면, 그저 평소와 같이 개별 질의 열 위의 출력 쿼리 중 하나를 사용하십시오. 그 결과 행, 즉 당 하나의 서비스 이름이됩니다 :

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

    당신이 보존해야 할 경우 그렇지 않으면, 쉼표 하나의 가능성은 사용하는 것입니다, 값을 구분 <= cfoutput과 그룹을 ".."> 쿼리 결과에. 결과는 첫 번째 "호스트", 아래의 코드 같은으로 정렬되어 있기 때문에. 주의 : 제대로 작동하려면 "그룹"에 대한 결과가 호스트로 주문해야합니다 아래와 같이 여러 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 :

    나는 MySQL은 cfoutput과 그룹에 대한 간단한 대안이 잊었 : 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>
    
  2. from https://stackoverflow.com/questions/25437697/sql-query-multiple-tables-with-multiple-joins-and-column-field-with-comma-separ by cc-by-sa and MIT license