2010-07-11 9 views
1

2 개의 조인 된 테이블이 있고 각 테이블에는 id라는 기본 키 열이 있습니다.다중 ID 열과 PHP가있는 mysql 쿼리

SELECT t1.*, t2.* from t1 join t2 on t1.fk_id=t2.id 

위 쿼리를 실행하면 두 id 필드 (t1.id 및 t2.id)가 선택됩니다. 내 질문은 결과 집합을 통해 반복하는 동안 올바른 ID를 어떻게 선택할 수 있습니까? $ result-> id를 선택하면 t2.id가 표시됩니다. t1.id를 쿼리에서 명시 적으로 선택하지 않고도 얻을 수있는 방법이 있습니까? (예 : t1.id는 t1_id입니까?) 또한 기본 키 열의 이름 지정과 관련하여 몇 가지 사례를 알려주십시오. .

감사합니다.

답변

8
SELECT t1.id as id1, t2.id as id2, t1.*, t2.* from t1 join t2 on t1.fk_id=t2.id 
+0

이것은 'id1'과'id2'를 사용하여 열을 참조 할 수있게 해준다. (또는' as xxx' to) –

+0

모두에게 감사드립니다! 나는 대개 명시 적으로 원하는 열을 선택하고 내 PKs 'id'의 이름을 지정하면됩니다. 내가 인수 한 프로젝트에는 테이블 이름에 대한 필드와 상수가 너무 많아서 모든 것을 입력하면 나에게 게으르다. – pistolshrimp

3

종종 XXX라는 xxx_id 테이블의 기본 키가 표시됩니다. 이것은 동일한 "정보 식별자"의 이름을 모든 곳에서 동일하게 유지합니다. 예를 들어 다른 테이블 YYY에서는 XXX.xxx_id에 외래 키 제약 조건이있는 YYY.xxx_id가 있습니다. 이렇게하면 조인이 더 쉬워집니다 (많은 데이터베이스에서 "on"제약 조건을 지정하지 않아도 됨). 그리고 실행중인 문제도 해결됩니다.

가짜 네임 스페이스를 만들기 위해 모든 열 이름 앞에 접두사를 붙이지 않아도되지만 "id"의 경우 실제로 유용하고 설명이 좋습니다. 그것은 결국 모든 종류의 ID가 아니라 사용자 ID, 사이트 ID, 게임 ID, 연락처 ID입니다.

+1

나는,이 방법 자신을 권하고 싶지 않다 :이 있지만 여전히 훨씬 더 쉽게 읽을 수 사물과 디버깅을 만드는 쿼리에 고유 한 열 이름을 사용하여, 중복 된 열 이름의 문제를 피해 갈 수 있습니다 CREATE TABLE과 같은 것들로 my_very_long_table_name (my_very_long_table_name_col1 INT, my_very_long_table_name_col2 INT); 그것은 모든 사람들에게 더욱 더 고통 스럽습니다. –

+0

죄송합니다, 그것은 혼란 스러웠습니다 - 답변을 업데이트했습니다. 나는 단순히 "id"를 사용하는 대신 기본 키의 이름을 지정하는 것을 의미했습니다. 모든 열에 접두어로 테이블 이름을 사용하는 것은 아닙니다. 그럼 다시, 내 자신의 SQL을 쓴 이후 그것은 일부 DSL/ORM을 통해 그것을 조작하지 않았다. – integer

3

mysqli_result::fetch_assoc을 사용하면 결과 집합의 각 행을 연관 배열로 반환 할 수 있습니다. MySQL에서는 질의에 같은 이름을 가진 두 개의 열을 갖게하지만 연관 배열이 정확히 수행해야하는 경우에도 연관 배열에 매핑 할 때 —을 지정합니다.

bookauthor의 두 테이블을 접합 테이블 book_author으로 연결한다고 가정합니다. MySQL의에서 두 id 열 반환 다음 쿼리를 실행할 수 있습니다 : 당신이 연관 배열에 이러한 행 중 하나를 매핑 할 경우

SELECT b.*, a.* 
FROM book AS b 
JOIN book_author AS ba ON ba.book_id = b.id 
JOIN author AS a ON a.id = ba.author_id 
LIMIT 2; 

+----+-----------------+----+--------------+ 
| id | title   | id | name   | 
+----+-----------------+----+--------------+ 
| 1 | Design Patterns | 1 | Erich Gamma | 
| 1 | Design Patterns | 2 | Richard Helm | 
+----+-----------------+----+--------------+ 

을, 당신은 당신의 배열에서 하나의 id 요소와 끝까지 :

$row = $result->fetch_assoc(); 
print_r($row); 

Array 
(
    [id] => 1 
    [title] => Design Patterns 
    [name] => Erich Gamma 
) 

행의 마지막 id 열은 그 앞에있는 모든 행을 덮어 씁니다. 여기 ’ 결과 세트에서 두 번째 행 S :

Array 
(
    [id] => 2 
    [title] => Design Patterns 
    [name] => Richard Helm 
) 

이것은 단지 연관 배열의 요소의 값을 수정 같은된다; 당신이 당신의 쿼리에서 어느 테이블 자체에 이렇게, 또는 그것을 쿼리에 별칭을 제공함으로써 각 열에 고유 한 이름을 지정하면

$row = array(); 
$row['id'] = 1; 
print_r($row); 
Array 
(
    [id] => 1 
) 

$row['id'] = 2; 
print_r($row); 
Array 
(
    [id] => 2 
) 

이 문제는 피할 수있다 : 또는

SELECT b.id AS book_id, b.title, 
    a.id AS author_id, a.name 
FROM book AS b 
JOIN book_author AS ba ON ba.book_id = b.id 
JOIN author AS a ON a.id = ba.author_id 
LIMIT 2; 

+---------+-----------------+-----------+--------------+ 
| book_id | title   | author_id | name   | 
+---------+-----------------+-----------+--------------+ 
|  1 | Design Patterns |   1 | Erich Gamma | 
|  1 | Design Patterns |   2 | Richard Helm | 
+---------+-----------------+-----------+--------------+ 

$row = $result->fetch_assoc(); 
print_r($row); 
Array 
(
    [book_id] => 1 
    [title] => Design Patterns 
    [author_id] => 1 
    [name] => Erich Gamma 
) 

, 대신 prepared statements을 사용할 수 있습니다.하나는 결국 경향이

$sql = 'SELECT b.*, a.* ' . 
    'FROM book AS b ' . 
    'JOIN book_author AS ba ' . 
    'ON ba.book_id = b.id ' . 
    'JOIN author AS a ' . 
    'ON a.id = ba.author_id'; 

$stmt = $mysqli->prepare($sql); 
$stmt->execute(); 
$stmt->bind_result($book_id, $book_title, $author_id, $author_name); 
while ($stmt->fetch()) { 
    printf("%s, %s, %s, %s\n", 
      $book_id, 
      $book_title, 
      $author_id, 
      $author_name); 
}