76

データベースに2つのテーブルがあります。

列のあるNEWSテーブル:

  • id-ニュースID
  • user-作成者のユーザーID)

列のあるUSERSテーブル:

  • id-ユーザーID

このSQLを実行したい:

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

PHPで結果を取得するとき、連想配列を取得し、列名をで取得したいと思います$row['column-name']。同じ列名のニュースIDとユーザーIDを取得するにはどうすればよいですか?

4

11 に答える 11

119

選択している列のエイリアスを設定できます。

$query = 'SELECT news.id AS newsId, user.id AS userId, [OTHER FIELDS HERE] FROM news JOIN users ON news.user = user.id'
于 2009-01-10T17:37:42.277 に答える
43

数値インデックス ( $row[0]) を使用することもAS、MySQLで使用することもできます。

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

于 2009-01-10T17:38:20.670 に答える
24

私はちょうどこれを理解しました。おそらく悪い習慣ですが、この場合はうまくいきました。

私は、すべての列名にテーブル プレフィックスを付けてエイリアスを作成したり、書き出したりしたくない怠け者の 1 人です。

table_name.*select ステートメントでを使用して、特定のテーブルからすべての列を選択できます。

列名が重複している場合、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上記の例では、 I getの値はfrom になります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おかしな列をすべて書き出す必要なく、必要な値を取得しましたが、それでもすべての列を操作できます。わーい!

dupの値が3 つのテーブルすべてで同じであることはわかっていますtable3が、 に一致する値がない場合はどうなりdupますか? 次にdup、最初の例では空白になり、それは残念なことです。

于 2009-11-14T02:11:53.663 に答える
12

@ジェイソン。mysql ではなく php が原因であることを除いて、あなたは正しいです。Mysql Workbench に配置するJOINと、まったく同じ名前 (テーブルごとに 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 で一部の情報が静かに失われます...

于 2011-08-31T20:03:31.563 に答える
11

別のヒント: よりクリーンな 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";
于 2011-10-14T16:24:46.890 に答える
9

次のようなことができます

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

そして$row['news_id']、ニュースID$row['user_id']になり、ユーザーIDになります

于 2009-01-10T17:38:40.217 に答える
3

動的テーブルでも同じ問題がありました。(結合できる ID を持つと想定されているテーブルですが、残りのフィールドについては想定されていません。) この場合、事前にエイリアスがわかりません。

このような場合、最初にすべての動的テーブルのテーブル列名を取得できます。

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

$zendDbInstance は Zend_Db のインスタンスです。または、Zend php pdo: get the columns name of a table に依存しないように、ここで関数の 1 つを使用できます。

次に、すべての動的テーブルに対してエイリアスを取得し、エイリアスが不要なものには $tableName.* を使用できます。

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

このプロセス全体を 1 つの汎用関数にラップして、よりクリーンなコードにするか、必要に応じてより遅延させることができます :)

于 2011-06-03T15:01:45.197 に答える
0

エイリアスを作成したくない場合は、テーブル名のプレフィックスを付けることもできます。

このようにして、クエリの生成をより適切に自動化できます。また、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
于 2009-01-10T21:34:12.673 に答える
0

これは上記に対する答えです。これは単純であり、JSON の結果が返されても機能します。SELECT * を使用すると、SQL クエリは同じフィールド名の各インスタンスにテーブル名のプレフィックスを自動的に付けますが、JSON エンコーディングの結果を Web ページに送り返すと、名前が重複するこれらのフィールドの値が無視され、代わりに NULL 値が返されます。 .

正確には、重複したフィールド名の最初のインスタンスを含めますが、その値を NULL にします。また、フィールド名の 2 番目のインスタンス (他のテーブル内) は、フィールド名と値の両方で完全に省略されています。ただし、クエリをデータベースで直接テストすると (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 ステートメントの最初に置く必要がありますが、列を繰り返し選択しても問題が発生しないため、その後に必要な数の名前付き列と別名列を含めることができます。

于 2020-02-19T04:24:37.827 に答える
-1

次の 2 つの方法があります。

  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];
    }
    
于 2017-01-18T15:10:08.090 に答える