2010-06-23 2 views
2

이 쿼리는 약간 기본적인 것 같아요. SQL에 대해 더 많이 알고 있어야하지만 조인을 많이하지는 않았지만 아직 해결 방법이 없다고 생각합니다.행을 복제하지 않고 2 SQL 테이블의 행을 병합하는 방법은 무엇입니까?

내가 가진 것은 사람들의 테이블과 그들이 지닌 직무에 대한 테이블입니다. 사람은 여러 개의 직업을 가질 수 있으며 세부 정보와 직업 역할이 포함 된 한 줄짜리 결과 집합을 원합니다.

두 개의 예제 테이블 (사람 및 직업)이 아래에 있으므로 쉽게 질문을 이해할 수 있습니다.

사람들

 
id | name | email_address | phone_number 
1 | paul | [email protected] | 123456 
2 | bob | [email protected] | 567891 
3 | bart | [email protected] | 987561 

job_roles 그래서 출력 할 수

 
id | person_id |  job_title | department 
    1 |  1  |  secretary | hr 
    2 |  1  |  assistant | media 
    3 |  2  |  manager | IT 
    4 |  3  | finance clerk | finance 
    4 |  3  |  manager | IT 

각 사람 및

 
Name: paul 
Email Address: [email protected] 
Phone: 123456 
Job Roles: 
Secretary for HR department 
Assistant for media department 
_______ 
Name: bob 
Email address: [email protected] 
Phone: 567891 
Job roles: 
Manager for IT department 

같은 역할 그래서에서 (각 사람의 정보를 얼마나 people 테이블)과 job details (job_roles 테이블)를 위의 예제와 같이 출력합니다. 나는 출력을 위해 나눌 수있는 작업 열로 자신의 직업과 관련 부서를 병합하는 일종의 방법이 될 것이라고 생각하지만, 아마 더 좋은 방법이 있고 SQL은 어떻게 생겼을까요? 즉 그것은 바로 앞으로 보이는 차이

답변

2

RE :

내가 기대했다 SQL 그래서 난 본질적으로 그 사람의 작업과 작업 열을했다 영리한 뭔가 을 멋지게 함께 을 행에 가입 할 수있다.

사용을 통해 다음

$people_array =array(); 
while($row1=mysql_fetch_assoc($extract1)){ 
$people_array[] = $row1; 
} 

및 루프를 사용하여 테이블을 외부 조인 왼쪽 다음 배열에 그들을로드 할 수 있습니다

SELECT p.id, p.name, p.email_address, p.phone_number, 
group_concat(concat(job_title, ' for ', department, ' department') SEPARATOR '\n') AS JobRoles 
FROM People AS p 
    INNER JOIN job_roles AS r ON p.id = r.person_id 
GROUP BY p.id, p.name, p.email_address, p.phone_number 
ORDER BY p.name; 
+1

감사합니다. 사용이 끝나고 잘 작동합니다. – AdrenalineJunky

+0

이것은 매우 영리하고 알아두면 편리하지만, 여전히 PHP에서 데이터를 정상적으로 조인하고 포맷하는 것을 선호합니다. 언젠가 일일 역할간에
을 추가하는 등의 형식을 변경하려면 SQL 쿼리를 수정해야합니다. GROUP_CONCAT은 DB 로직과 프리젠 테이션의 분리를 제거합니다. 또한 단위 테스트를 훨씬 어렵게 만듭니다. – dave1010

3

을 만드는 경우

감사

PS는 MySQL 데이터베이스 것 가입 :

SELECT p.*, j.* 
    FROM People AS p INNER JOIN Roles AS r ON p.id = r.person_id 
ORDER BY p.name; 

의 나머지 작업은 포맷이다. 보고서 패키지를 사용하는 것이 가장 좋습니다. 좋은 시작을 보인다하지만 당신은 당신이 상상이 (같은 사람 당 여러 행을 얻을 빠른 응답을위한


감사는 의견 포맷 할 수있을 것하지 않는 테이블입니다)이 가능하다면

id | Name | email_address | phone_number | job_role | department 
1 | paul | [email protected] | 123456  | secretary | HR 
1 | paul | [email protected] | 123456  | assistant | media 
2 | bob | [email protected] | 567891  | manager | IT 

내가 모든 직무 역할과 이상적으로 사람 당 하나 개의 행을 원하십니까?

DBMS에 따라 다르지만 대부분 사용 가능한 것들은 RVAs - 관계형 속성을 지원하지 않습니다. 당신이 원하는 것은 사용자와 관련된 테이블과 같은 결과의 직무와 부서 부분을하는 것입니다 :

+----+------+------------------+--------------+------------------------+ 
| id | Name | email_address | phone_number | dept_role   | 
+----+------+------------------+--------------+------------------------+ 
| |  |     |    | +--------------------+ | 
| |  |     |    | | job_role | dept | | 
| 1 | paul | [email protected] | 123456  | | secretary | HR | | 
| |  |     |    | | assistant | media | | 
| |  |     |    | +--------------------+ | 
+----+------+------------------+--------------+------------------------+ 
| |  |     |    | +--------------------+ | 
| |  |     |    | | job_role | dept | | 
| 2 | bob | [email protected] | 567891  | | manager | IT | | 
| |  |     |    | +--------------------+ | 
+----+------+------------------+--------------+------------------------+ 

이 정확하게 원하는 정보를 나타내며,하지만 일반적으로 옵션이 아닙니다.

그러면 다음 단계는 보고서 생성 도구에 따라 다릅니다.필자가 가장 익숙한 Informix ACE (IBM Informix DBMS와 함께 사용할 수있는 Informix SQL의 일부인 Informix ACE)를 사용하면 데이터가 정렬되었는지 확인한 다음 이름, 전자 메일 주소 및 전화 번호 보고서의 'BEFORE GROUP OF ID'섹션에서 '모든 행에'섹션에서 역할 및 부서 정보 만 처리 (인쇄)합니다.

보고서 형식을 데이터 검색 작업과 구분하는 것이 좋습니다. 이것은 DBMS가 선택된 데이터의 포맷을 돕기 위해 특이한 기능을 가지고 있지 않는 한 필요한 곳의 예입니다.


매우 복잡 소리와 뭔가 내가 PHP 페이지에서 MySQL 데이터베이스에 쉽게 실행할 수 없습니다

오, 친애하는?

RVA는 당신이 맞습니다. 그것은 MySQL과 PHP가 아닙니다.

반면에 대략적으로 수행되는 수백만 개의 보고서 (사용자에게 표시하기 위해 형식화 된 쿼리의 결과를 의미 함)가 있습니다. 그들에 대한 기술적 용어는 'Control-Break Report'이지만 기본 아이디어는 그리 어렵지 않습니다.

마지막으로 처리 한 'id'번호의 기록을 유지합니다. -1 또는 0으로 초기화 할 수 있습니다. 현재 레코드의 이전 번호와 다른 ID 번호가있는 경우 새 사용자가 있고 새 사용자에 대한 새로운 출력 행 세트를 시작하고 이름, 이메일 주소 및 전화 번호를 인쇄하고 마지막으로 처리 된 ID 번호를 변경해야합니다. 현재 레코드의 ID 번호가 같으면 직책과 부서 정보 (이름, 전자 메일 주소 및 전화 번호 제외)를 처리하는 것뿐입니다. '중단'은 ID 번호가 변경 될 때 발생합니다. 단일 수준의 제어 중단으로 인해 어렵지 않습니다. 4 단계 또는 5 단계가 있다면 더 많은 작업을해야하기 때문에이를 처리 할 패키지를보고하는 것입니다.

그래서 어렵지 않습니다. 단지 조금만 신경 써야합니다.

+0

+1 : 나를 때려 줘요. 시각적으로 JOIN을 나타냄) [http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html] –

+0

빠른 응답 주셔서 감사합니다. 좋은 시작 인 것 같지만 사람마다 여러 개의 행이 있습니다 (주석으로 서식을 지정할 수없는 것처럼 테이블이 있다고 상상해보십시오) : id | 이름 | email_address | phone_number | job_role | 부서 1 | 폴 | [email protected] | 123456 | 비서 | HR 1 | 폴 | [email protected] | 123456 | 조수 | 미디어 2 | 밥 | [email protected] | 567891 | 관리자 | IT 가능하다면 사람마다 한 줄의 모든 역할을 맡고 싶습니다. – AdrenalineJunky

+0

매우 복잡하고 쉽게 PHP 페이지의 mySQL 데이터베이스에서 실행할 수없는 것 같습니다. – AdrenalineJunky

0

원하는 방식대로 수행하면 결과 집합 배열이 무한한 열을 가질 수 있으며 이는 매우 혼란 스러울 수 있습니다. 예를 들어 jobs 테이블에 10 번 참여하여 job1, job2, .. job10을 얻을 수 있습니다.

단일 조인을 한 다음 PHP를 사용하여 이름 ID가 1 행에서 다음 행까지 동일한지 확인합니다.

+0

고마워요, 그 결론은 내가 왔지만 SQL이 뭔가 영리한 일을 할 수 있었으면 좋겠고 행을 멋지게 결합 ​​할 수 있기를 바랬습니다. – AdrenalineJunky

0

방법 중 하나와 비슷한 얻을 수 있습니다

for ($x=0;$x<=sizeof($people_array;) 
    { 
echo $people_array[$x][id]; 
echo $people_array[$x][name]; 

for($y=0;$y<=$number_of_roles;$y++) 
{ 
echo $people_array[$x][email_address]; 
echo $people_array[$x][phone_number]; 
    $x++; 
} 
    } 

약간의 루프와 루프를 쿼리하지만 일반적으로 원하는 것을해야합니다.위와 같이 작동하려면 모든 사람이 같은 역할의 숫자를 가져야하지만 테이블의 공백을 채울 수 있습니다.

+0

좋은 생각이지만 그룹 concat은 더 깨끗한 솔루션 인 것으로 보입니다. – AdrenalineJunky

관련 문제