2017-07-25 4 views
1

これは愚かな質問ですが、申し訳ありませんが、私はそれの周りに私の頭を得るように見えることはできません。私はかなりSQLに慣れています。この動作は、RやPandasなど、私が使用するのに慣れているのは変です。SQLで、なぜこのJOINがキー列を2回返すのですか?

基本的に2つの異なるデータベースに共通のキーuser_idを持つ2つのテーブルがあります。私はすべての列に参加したい

SELECT * FROM db1.first_table t1 
JOIN db2.second_table t2 
ON t1.user_id = t2.user_id 

偉大な、それは動作します。ただし、user_idという2つの(同一の)列はありません。これは本当に重要なことではありませんが、私はpysparkでこれをやっていますが、結合したテーブルをフラットファイルにエクスポートしようとすると、2つのカラムが同じ名前を持つというエラーが発生します。これには回避策がありますが、なぜ誰かがなぜ返り値がで返ってくるのかを説明できるかどうかは不思議です。user_idカラム。それは内部結合であるように見えるので、定義によって列は同一です。なぜそれは両方を返すだろうか?

副次的な質問として、この動作を回避する簡単な方法はありますか?

ありがとうございます!

+1

"select *"は両方のテーブルのすべてのカラムを返すためです。あなたが制限する必要がある場合、明示的に定義するtable.columns – OldProgrammer

+0

を使用しているため、あなたはそれが結合のすべてのテーブルのすべての列を返すことを意味します – Lamak

+0

回避策? 'select *'を使うのは実際にはあまり良いことではないので、検索する列を常に定義する必要があります。それは回避策ではありません - それはあなたがそれを行うべきです! –

答えて

2

SELECT *は、クエリのすべてのテーブルからすべての列を返します。これは、両方のuser_idの列が含まれています - テーブルAから1、テーブルBのベストプラクティスは、あなたが特に返さたい列名をリストすることです

から1、リストを短くする別のオプションは以下のようになりかかわら:

SELECT TableA.*, 
     TableB.col1, 
     TableB.col2, 
     ...rest of B columns except user_id 
1

Select *を使用しているためです。 *SELECTの後に定義されている場合、両方のテーブルからすべての列が戻されます。列名を定義する必要があります。常に表示する列を定義します。あなたはこのような何かを行うことができます。

SELECT t1.userid, t1.ColumnName1, t2.ColumnName2 
FROM db1.first_table t1 
INNER JOIN db2.second_table t2 ON t1.user_id = t2.user_id 

*は、次のように使用することができます。

次のクエリでは、両方のテーブルからすべての列を返します。

SELECT * 
FROM db1.first_table t1 
INNER JOIN db2.second_table t2 ON t1.user_id = t2.user_id 

次のクエリからすべての列を返します。 first_tableテーブル:

SELECT t1.* 
FROM db1.first_table t1 
INNER JOIN db2.second_table t2 ON t1.user_id = t2.user_id 

次のクエリはSecond_tableテーブルからすべての列を返す:

SELECT t2.* 
FROM db1.first_table t1 
INNER JOIN db2.second_table t2 ON t1.user_id = t2.user_id 

また、あなたは、このように他のテーブルから一つのテーブルや特定の列からすべての列を取得することができます。

SELECT t1.*, t2.ColumnName 
FROM db1.first_table t1 
INNER JOIN db2.second_table t2 ON t1.user_id = t2.user_id 
1

あなたは何を参照するフィールドの数を減らすことができますあなたが望むフィールド。

今あなたが

SELECT t1.*, t2.* 

に等しく、たぶん、あなたは[OK]を、私は入力しなくてもこれを行う方法を考え出し

SELECT t1.*, t2.field1, t2.field2 ... 
0

ような何かをしたい

SELECT * 

を持っていますすべての列名を削除します(コメントに記載されているとおり、〜5k列の合計があります)。

これはpysparkに固有のものですが、私はちょうどCSVファイルに列名をエクスポートし、それらをロードし、次のようでした:

with open("t1_cols.csv") as data_file:  
    t1_cols = data_file.read().split('\n') 
with open("t2_cols.csv") as data_file:  
    t2_cols = data_file.read().split('\n') 

sql = 'SELECT t1.user_id, t1.' + ', t1.'.join(t1_cols) + \ 
', t2.' + ', t2.'.join(t2_cols) + ' ' + \ 
'FROM db1.first_table t1 JOIN db2.second_table t2 ON t1.user_id = t2.user_id' 

df = sqlContext.sql(sql) 

少し不快な、それが働きました。

また、上記の回答のすべてが技術的に正しいため、最初の回答が受け入れられました。助けてくれてありがとう!

関連する問題