对不起,如果这是一个愚蠢的问题,但我似乎无法理解它。我对SQL很新,这种行为在R或Pandas或我曾经使用过的其他东西中会很奇怪。
基本上,我在两个不同的数据库中有两个表,共有一个密钥user_id
。我想用
SELECT * FROM db1.first_table t1
JOIN db2.second_table t2
ON t1.user_id = t2.user_id
很好,它有效。除了有两个(相同的)列称为user_id
。这并不重要,除了我在pyspark中这样做,当我尝试将连接表导出到平面文件时,我得到一个错误,其中两列具有相同的名称。有一些解决方法,但我想知道是否有人可以解释为什么连接返回两个 user_id
列。看起来它是一个内连接,所以根据定义,列是相同的。为什么会同时返回?
作为一个附带问题,是否有一种简单的方法可以避免这种行为?
提前致谢!
答案 0 :(得分:2)
所有这些答案(OP自己写的答案除外)似乎都假定我们在非常小的表上进行操作,可以在其中手动键入所需的每一列。
PySpark中最简单的解决方案是使用DataFrame连接语法:
Object.const_get(c)
这不会重复该列,其行为类似于熊猫合并。如果没有特殊原因必须将其编写为sql命令,则建议这样做。将此与
对比df = left_df.join(right_df, ["name"])
行为类似于SQL连接并保留两列!
这也适用于Scala和R see here。
另一种解决方案是将第二个目标列重命名为“ target_dataframe2”,然后与sql联接,然后再次简单地删除“ target_dataframe2”。
答案 1 :(得分:1)
SELECT *
返回查询的所有表中的所有列。这包括user_id
列 - 一个来自表A,一个来自表B.
最佳做法是列出您想要专门返回的列名称,但缩短列表的另一个选项是:
SELECT TableA.*,
TableB.col1,
TableB.col2,
...rest of B columns except user_id
答案 2 :(得分:1)
您可以减少引用所需字段的字段数。
现在你有
SELECT *
等于
SELECT t1.*, t2.*
也许你想要像
这样的东西 SELECT t1.*, t2.field1, t2.field2 ...
答案 3 :(得分:1)
好的,我想办法在不输入所有列名的情况下这样做(正如我在评论中提到的那样,总共有~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)
有点讨厌,但它奏效了。
另外,我接受了第一个答案,因为所有上述答案在技术上都是正确的,这是第一个答案。谢谢你的帮助!
答案 4 :(得分:0)
这是因为您使用的是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