programing

결과를 검색할 때 모호한 열 이름을 해결하는 방법은 무엇입니까?

kingscode 2023. 1. 22. 22:36
반응형

결과를 검색할 때 모호한 열 이름을 해결하는 방법은 무엇입니까?

데이터베이스에는 다음 두 개의 테이블이 있습니다.

열이 있는 NEWS 테이블:

  • id- 뉴스 아이디
  • user- 작성자의 사용자 ID)

열이 있는 USER 테이블:

  • id- 사용자 ID

다음 SQL을 실행합니다.

SELECT * FROM news JOIN users ON news.user = user.id 

PHP에서 결과를 얻었을 때 연관 배열과 열 이름을 가져오고 싶습니다.$row['column-name']같은 컬럼 이름을 가진 뉴스 ID와 사용자 ID를 얻으려면 어떻게 해야 하나요?

선택한 열의 에일리어스를 설정할 수 있습니다.

$query = 'SELECT news.id AS newsId, user.id AS userId, [OTHER FIELDS HERE] FROM news JOIN users ON news.user = user.id'

숫자 인덱스를 사용할 수 있습니다($row[0]) 이상, 사용ASMySQL에서 다음을 수행합니다.

SELECT *, user.id AS user_id FROM ...

방금 알아냈어나쁜 관행일 수도 있지만 이번 경우에는 효과가 있었어요.

저는 모든 컬럼 이름에 표 접두사를 붙이거나 쓰고 싶지 않은 게으른 사람 중 한 명입니다.

를 사용하여 특정 테이블에서 모든 열을 선택할 수 있습니다.table_name.*를 참조해 주세요.

열 이름이 중복되면 mysql이 처음에서 마지막으로 덮어씁니다.처음 복제된 열 이름의 데이터는 해당 열 이름이 다시 발견되면 덮어씁니다.마지막으로 온 중복된 열 이름이 이깁니다.

각각 중복된 열 이름을 포함하는 3개의 테이블을 결합하는 경우, select 스테이트먼트의 테이블 순서에 따라 중복된 열에 대해 가져올 데이터가 결정됩니다.

예:

SELECT table1.* , table2.* , table3.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup;

위의 예에서 값은 다음과 같은 값입니다.dup내가 얻는 것은table3.

내가 원한다면?dup값어치가 있다table1?

그럼 이렇게 해야겠네요.

SELECT table3.* , table2.* , table1.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup;

지금이다,table1마지막이 되기 때문에 가치 있는 것은duptable1의 값이 됩니다.

원하는 가치를 얻을 수 있었습니다.dup모든 칼럼을 다 쓸 필요 없이 모든 칼럼을 쓸 수 있어요아싸!

의 가치를 알고 있다dup3개의 테이블 모두 동일해야 하는데table3에 일치하는 값이 없습니다.dup그럼?dup첫 번째 예에서는 공백이 될 것이고, 그러면 아쉬울 것입니다.

@Jason. php가 mysql이 아닌 범인임을 제외하면 당신이 옳습니다.를 붙이면JOINMysql Workbench에서는 동일한 이름(테이블마다 1개씩)을 가진 3개의 컬럼이 표시됩니다(일부 컬럼은null그 테이블이 에 필적하지 않는 경우JOIN).

php(사용하는 경우)MYSQL_NUMmysql_fetch_array()그러면 모든 열이 표시됩니다.는 '어울릴 때'를 할 때 입니다.mysql_fetch_array()MYSQL_ASSOC그리고 이 함수 안에서 php는 다음과 같이 반환값을 작성합니다.

$row['dup'] = [value from table1]

나중에...

$row['dup'] = [value from table2]

...

$row['dup'] = [value from table3]

따라서 table3의 값만 얻을 수 있습니다.문제는 mysql의 결과 세트에 같은 이름의 열이 포함될 수 있지만 php의 관련 배열은 배열에 중복된 키를 허용하지 않는다는 것입니다.데이터가 관련 배열, php에 저장되면 일부 정보가 자동으로 손실됩니다.

또 다른 힌트: 더 깨끗한 PHP 코드를 원하는 경우 데이터베이스에 VIEW를 만들 수 있습니다.

예를 들어 다음과 같습니다.

CREATE VIEW view_news AS
SELECT
  news.id news_id,
  user.id user_id,
  user.name user_name,
  [ OTHER FIELDS ]
FROM news, users
WHERE news.user_id = user.id;

PHP의 경우:

$sql = "SELECT * FROM view_news";

뭐 이런 거 할 수 있어요

SELECT news.id as news_id, user.id as user_id ....

다음에 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ.$row['news_id']가 되고, "News id"가 됩니다.$row['user_id'].

동적 테이블에서도 동일한 문제가 발생했습니다(다른 필드에서는 아무런 가정 없이 가입할 수 있는 ID가 있는 테이블).이 경우 사전에 가명을 알 수 없습니다.

이 경우 먼저 모든 동적 테이블의 테이블 열 이름을 가져올 수 있습니다.

$tblFields = array_keys($zendDbInstance->describeTable($tableName));

여기서 $zendDb인스턴스는 Zend_Db의 인스턴스이거나 Zend php pdo에 의존하지 않기 위해 여기에 있는 함수 중 하나를 사용할 수 있습니다: 테이블의 열 이름을 가져옵니다.

그런 다음 모든 동적 테이블에 대해 에일리어스를 가져와 $tableName을 사용할 수 있습니다.* 가명이 필요 없는 경우:

$aliases = "";
foreach($tblKeys as $field)
    $aliases .= $tableName . '.' . $field . ' AS ' . $tableName . '_' . $field . ',' ;
$aliases = trim($aliases, ',');

이 모든 프로세스를 하나의 범용 함수로 정리하여 코드를 정리하거나 필요에 따라 귀찮아질 수 있습니다.

데이터베이스 상호 작용에 PDO를 사용하는 경우 PDO를 사용할 수 있습니다.문제 해결에 도움이 될 수 있는 FETCH_NAME 가져오기 모드:

$sql = "SELECT * FROM news JOIN users ON news.user = user.id";
$data = $pdo->query($sql)->fetchAll(PDO::FETCH_NAMED);
foreach ($data as $row) {
    echo $row['column-name'][0]; // from the news table
    echo $row['column-name'][1]; // from the users table
    echo $row['other-column']; // any unique column name
}

에일리어스가 필요 없는 경우는, 태블네임 앞에 붙이면 됩니다.

이렇게 하면 쿼리 생성을 더 잘 자동화할 수 있습니다.또한 select *를 사용하지 않는 것이 좋습니다(필요한 필드를 선택하는 것보다 속도가 느린 것은 분명합니다).또한 원하는 필드의 이름만 명시적으로 지정합니다.

SELECT
    news.id, news.title, news.author, news.posted, 
    users.id, users.name, users.registered 
FROM 
    news 
LEFT JOIN 
    users 
ON 
    news.user = user.id

위의 답변은 간단하며 JSON 결과가 반환되는 경우에도 작동합니다.SELECT * 를 사용하면 SQL 쿼리에서 동일한 필드 이름의 각 인스턴스에 테이블 이름이 자동으로 프리픽스 됩니다만, 결과의 JSON 인코딩은 중복된 이름의 필드 값을 무시하고 대신 NULL 값을 반환합니다.

정확히는 복제된 필드 이름의 첫 번째 인스턴스가 포함되지만 그 값은 NULL이 됩니다.그리고 필드 이름의 두 번째 인스턴스(다른 테이블)는 필드 이름과 값 모두 모두 생략됩니다.단, 데이터베이스에서 직접 쿼리를 테스트하면(Navicat 사용 등) 결과 세트에 모든 필드가 반환됩니다.다음에 해당 결과의 JSON 인코딩을 수행할 때만 NULL 값을 가지며 이후 중복 이름은 완전히 생략됩니다.

따라서 이 문제를 쉽게 해결할 수 있는 방법은 먼저 SELECT *를 실행하고 다음으로 중복되는 에일리어스 필드를 작성하는 것입니다.다음은 두 테이블의 이름이 동일한 site_name 필드가 있는 예입니다.

SELECT *, w.site_name AS wo_site_name FROM ws_work_orders w JOIN ws_inspections i WHERE w.hma_num NOT IN(SELECT hma_number FROM ws_inspections) ORDER BY CAST(w.hma_num AS UNSIGNED);

디코딩된 JSON에서는 wo_site_name 필드를 사용할 수 있으며 값이 지정됩니다.이 경우 사이트 이름에는 아포스트로피나 작은 따옴표 등의 특수 문자가 포함되어 있기 때문에 최초 저장 시 인코딩, 데이터베이스 결과 사용 시 디코딩이 이루어집니다.

...decHTMLifEnc(decodeURIComponent( jsArrInspections[x]["wo_site_name"]))

항상 SELECT 문에는 *를 먼저 넣어야 하지만, 그 후에는 원하는 수만큼 이름이 지정된 열과 별칭이 지정된 열을 포함할 수 있습니다. 열을 반복해서 선택하면 문제가 발생하지 않습니다.

두 가지 접근법이 있습니다.

  1. 별칭을 사용합니다. 이 방법에서는 다양한 열에 새로운 고유 이름(ALIAS)을 지정한 후 PHP 검색에서 사용합니다.

    SELECT student_id AS FEES_LINK, student_class AS CLASS_LINK 
    FROM students_fee_tbl 
    LEFT JOIN student_class_tbl ON students_fee_tbl.student_id = student_class_tbl.student_id
    

    결과를 PHP로 가져옵니다.

    $query = $PDO_stmt->fetchAll();
    
    foreach($query as $q) {
        echo $q['FEES_LINK'];
    }
    
  2. 장소 위치 또는 결과 집합 열 색인을 사용합니다. 여기서 배열 위치는 중복된 열 이름을 참조하는 데 사용됩니다.서로 다른 위치에 나타나기 때문에 사용되는 인덱스 번호는 항상 고유합니다.단, 지수 포지셔닝 번호는 0부터 시작한다.

    SELECT student_id, student_class 
    FROM students_fee_tbl 
    LEFT JOIN student_class_tbl ON students_fee_tbl.student_id = student_class_tbl.student_id
    

    결과를 PHP로 가져옵니다.

    $query = $PDO_stmt->fetchAll();
    
    foreach($query as $q) {
        echo $q[0];
    }
    

언급URL : https://stackoverflow.com/questions/431391/how-to-resolve-ambiguous-column-names-when-retrieving-results

반응형