当前位置: 首页 > 知识库问答 >
问题:

在Spark SQL中连接2个以上的表

程举
2023-03-14

我试图用SPARK SQL编写一个查询,执行三个表的联接。但是查询输出实际上是null。它适用于单人餐桌。我的联接查询是正确的,因为我已经在oracle数据库中执行了它。我需要在这里附加什么更正?Spark版本是2.0.0。

from pyspark.sql import SQLContext, Row
sqlContext = SQLContext(sc)

lines = sc.textFile("/Users/Hadoop_IPFile/purchase")
lines2 = sc.textFile("/Users/Hadoop_IPFile/customer")
lines3 = sc.textFile("/Users/Hadoop_IPFile/book")

parts = lines.map(lambda l: l.split("\t"))
purchase = parts.map(lambda p: Row(year=p[0],cid=p[1],isbn=p[2],seller=p[3],price=int(p[4])))
schemapurchase = sqlContext.createDataFrame(purchase)
schemapurchase.registerTempTable("purchase")


parts2 = lines.map(lambda l: l.split("\t"))
customer = parts2.map(lambda p: Row(cid=p[0],name=p[1],age=p[2],city=p[3],sex=p[4]))
schemacustomer = sqlContext.createDataFrame(customer)
schemacustomer.registerTempTable("customer")

parts3 = lines.map(lambda l: l.split("\t"))
book = parts3.map(lambda p: Row(isbn=p[0],name=p[1]))
schemabook = sqlContext.createDataFrame(book)
schemabook.registerTempTable("book")

result_purchase = sqlContext.sql("""SELECT DISTINCT customer.name AS name FROM purchase JOIN book ON purchase.isbn = book.isbn JOIN customer ON customer.cid = purchase.cid WHERE customer.name != 'Harry Smith' AND purchase.isbn IN (SELECT purchase.isbn FROM customer JOIN purchase ON customer.cid = purchase.cid WHERE customer.name = 'Harry Smith')""")

result = result_purchase.rdd.map(lambda p: "name: " + p.name).collect()
for name in result:
    print(name)


DataSet
---------
Purchase
1999    C1  B1  Amazon  90
2001    C1  B2  Amazon  20
2008    C2  B2  Barnes Noble    30
2008    C3  B3  Amazon  28
2009    C2  B1  Borders 90
2010    C4  B3  Barnes Noble    26


Customer
C1  Jackie Chan 50  Dayton  M
C2  Harry Smith 30  Beavercreek M
C3  Ellen Smith 28  Beavercreek F
C4  John Chan   20  Dayton  M

Book
B1  Novel
B2  Drama
B3  Poem

我在一些网页上发现了下面的说明,但它仍然不起作用:

schemapurchase.join(schemabook, schemapurchase.isbn == schemabook.isbn) 
schemapurchase.join(schemacustomer, schemapurchase.cid == schemacustomer.cid)

共有1个答案

轩辕源
2023-03-14

给定输入数据,如您的示例中所示(抱歉,如果某些列名是错误的,我猜到了):

购买:

+----+---+----+------------+-----+
|year|cid|isbn|        shop|price|
+----+---+----+------------+-----+
|1999| C1|  B1|      Amazon|   90|
|2001| C1|  B2|      Amazon|   20|
|2008| C2|  B2|Barnes Noble|   30|
|2008| C3|  B3|      Amazon|   28|
|2009| C2|  B1|     Borders|   90|
|2010| C4|  B3|Barnes Noble|   26|
+----+---+----+------------+-----+

客户:

+---+-----------+---+-----------+-----+
|cid|       name|age|       city|genre|
+---+-----------+---+-----------+-----+
| C1|Jackie Chan| 50|     Dayton|    M|
| C2|Harry Smith| 30|Beavercreek|    M|
| C3|Ellen Smith| 28|Beavercreek|    F|
| C4|  John Chan| 20|     Dayton|    M|
+---+-----------+---+-----------+-----+
+----+-----+
|isbn|genre|
+----+-----+
|  B1|Novel|
|  B2|Drama|
|  B3| Poem|
+----+-----+
val result = purchase.join(book, purchase("isbn")===book("isbn"))
                     .join(customer, customer("cid")===purchase("cid"))
                     .where(customer("name") !== "Harry Smith")
                     .join(temp, purchase("isbn")===temp("purchase_isbn"))
                     .select(customer("name").as("NAME")).distinct()
val temp = customer.join(purchase, customer("cid")===purchase("cid") )
                   .where(customer("name")==="Harry Smith")
                   .select(purchase("isbn").as("purchase_isbn"))    


+-------------+
|purchase_isbn|
+-------------+
|           B2|
|           B1|
+-------------+
+-----------+
|       NAME|
+-----------+
|Jackie Chan|
+-----------+
 类似资料:
  • 我有3个不同类型的键控数据流。 我不能使用联合(允许多个数据流),因为类型不同。我希望避免创建包装器,并将所有流转换为相同的类型。

  • 问题内容: 当我运行以下查询 我收到一个错误“ ” 问题答案: Concat仅接受两个参数。请参阅:http : //docs.oracle.com/cd/B19306_01/server.102/b14200/functions026.htm 使用串联运算符:

  • 有没有办法通过两个列表< code>join两个< code > Spark data frame 具有不同的列名? 我知道如果他们在列表中有相同的名字,我可以做以下事情: 或者,如果我知道不同的列名,我可以这样做: 由于我的方法需要2个列表的输入,这些列表指定哪些列将用于每个DF的,因此我想知道Scala Spark是否有办法做到这一点? 页(page的缩写)我在寻找类似python的东西< c

  • 此外,它在spark cassandra Connector1.4中工作,但不是与最新的cassandra Connector1.6.0-M1一起工作。请让我知道这个问题

  • 问题内容: 我有2张桌子。为了简化: 表1,用户: userId int,userName nvarchar(50) 表2消息: msgId int,msgFrom int,msgTo int … msg1和msg2都包含userId。现在,我想获取所有消息,但是我想要用户名而不是msgFrom。我知道该怎么办: 一切正常,花花公子。获取用户名而不是msgTo的方法相同。现在的问题是,如何在同一调

  • 问题内容: 我有第一个数据库 (dbA), 具有这样的表,名为 Username : 然后,在另一侧,我有 一个 带有这样的表的 dbB ,名为 PrivateMessage : 现在,如何组合来自2个不同数据库的这两个表,以便输出看起来像这样: 问题答案: 您可以简单地加入不同数据库的表。您需要在子句中指定数据库名称。要使其更短,请在其上添加一个, 但是有些方法却有可能-在其中没有消息。在这种情