基于条件在Spark SQL或MySQL中生成新列

基于条件在Spark SQL或MySQL中生成新列,mysql,sql,pyspark,Mysql,Sql,Pyspark,表格创建: CREATE TABLE temp ( name varchar(20), dep varchar(20)); INSERT INTO temp VALUES ('a', null), ('b', null), ('c', 'b'), ('d', 'c'), ('e', 'b'), ('e', 'd'); 我需要社区帮助来编写一个生成新列的查询,比如说xyz,如果dep为空,则该列的值为1。否则,它必须对相应的名称采用dep,并在xyz列值中添加1 例如:这里c依赖

表格创建:

CREATE TABLE temp (
name varchar(20), 
dep varchar(20));

INSERT INTO temp VALUES 
('a', null), 
('b', null), 
('c', 'b'), 
('d', 'c'), 
('e', 'b'), 
('e', 'd');
我需要社区帮助来编写一个生成新列的查询,比如说xyz,如果dep为空,则该列的值为1。否则,它必须对相应的名称采用dep,并在xyz列值中添加1

例如:这里c依赖于b,因此它必须取bxyz,该值为1,并加上1,从而将cxyz值设为2,依此类推

输出:

+------+------+-----+
| name |  dep | xyz |
+------+------+-----+
|  a   | null |  1  |
|  b   | null |  1  |
|  c   |  b   |  2  |
|  d   |  c   |  3  |
|  e   |  b   |  2  |
|  e   |  d   |  4  |
+------+------+-----+
表格创建:

CREATE TABLE temp (
name varchar(20), 
dep varchar(20));

INSERT INTO temp VALUES 
('a', null), 
('b', null), 
('c', 'b'), 
('d', 'c'), 
('e', 'b'), 
('e', 'd');
创建表temp1(名称varchar(20),依赖项varchar(20));
插入到temp1值中
('city',null),('state',null),('country',city'),
('country','state'),('pin','country'),('pin','state'),
(‘大陆’、‘国家’、(‘大陆’、‘宾’)、(‘大陆’、‘城市’);
预期输出:此处序列是要生成的新列

|名称|依赖项|序列|
|----------|------------|----------|
|城市|空| 1|
|州|空| 1|
|乡村|城市| 2|
|国家|州| 2|
|别针|国家| 3|
|引脚|状态| 2|
|大陆|国家| 3|
|大陆|针| 4|
|大陆|城市| 2|
我向社区提出的第一个问题:) 提前感谢大家。

试试这个,看看我的SQL 8.0

select
  name,
  dep,
  dense_rank() over (order by dep) as xyz
from myTable
order by
  name, dep
输出:

+--------------+
name  dep   xyz
+--------------+
 a  (null)   1
 b  (null)   1
 c    b      2
 d    c      3
 e    b      2
 e    d      4
+--------------------------+
name        type      ranks
+--------------------------+
city        null        1
state       null        1
country     city        2
country     state       2
pin         country     3
pin         state       2
continent   country     3
continent   pin         4
continent   city        2
对于第二个问题,您可以通过以下简单的
case
语句来实现

select
    name,
    type,
    case
    when 
        (name = 'country' and type = 'city') 
        OR (name = 'continent' and type = 'city')
        OR (name = 'pin' and type = 'state')
        OR (name = 'country' and type = 'state') 
    then
        2
    when
        (name = 'pin' and type = 'country')
        OR (name = 'continent' and type = 'country')
    then
        3
    when
        (name = 'continent' and type = 'pin')
    then
        4
    else
        1
    end as ranks
from myTable
输出:

+--------------+
name  dep   xyz
+--------------+
 a  (null)   1
 b  (null)   1
 c    b      2
 d    c      3
 e    b      2
 e    d      4
+--------------------------+
name        type      ranks
+--------------------------+
city        null        1
state       null        1
country     city        2
country     state       2
pin         country     3
pin         state       2
continent   country     3
continent   pin         4
continent   city        2

@热情的回答似乎起到了作用

我可以向您推荐等效的
pyspark
语法(因为
pyspark
在标记中)

首先,创建数据帧

将pyspark.sql.window导入为psw
将pyspark.sql.functions作为psf导入
​df=spark.createDataFrame([(“a”,无,1),(“b”,无,1),
(c,b,2),(d,c,3),,
(e,b,2,(e,d,4),,
['name'、'dep'、'xyz'])
df.show(5)
+----+----+---+
|名称| dep | xyz|
+----+----+---+
|a |空| 1|
|b |空| 1|
|c | b | 2|
|d | c | 3|
|e | b | 2|
+----+----+---+
仅显示前5行
其思想是按
dep
排序:
Null
首先是值,然后得到字母的顺序。使用
psf.densite\u rank
,您的订单中没有空白。要在
Spark
中应用
densite\u-rank
,您需要一个
窗口
功能:

w=psw.Window.orderBy('dep'))
df.withColumn(“xyz”,psf.densite_rank()。在(w)上方)
​
df.show(5)
+----+----+---+
|名称| dep | xyz|
+----+----+---+
|a |空| 1|
|b |空| 1|
|c | b | 2|
|d | c | 3|
|e | b | 2|
+----+----+---+
仅显示前5行
更新 对于你的第二个问题,我没有看到任何模式允许优雅的解决方案。您将需要一系列
psf.when
语句

import pyspark.sql.函数作为psf
df=spark.createDataFrame([('city',None),('state',None),
(‘国家’、‘城市’、(‘国家’、‘州’),
('pin','country'),('pin','state'),
(‘大陆’、‘国家’、(‘大陆’、‘别针’),
(‘大陆’、‘城市’)]、[‘名称’、‘类型’])
df=df.withColumn(“序列”),psf.when(
((psf.col('name')='country')和(psf.col('type')='city'))|
((psf.col(‘名称’=‘大陆’)和(psf.col(‘类型’=‘城市’))|
((psf.col('name')=“pin”)&(psf.col('type')=“state”))|
((psf.col('name')='country')和(psf.col('type')='state”),
2.
).什么时候(
((psf.col('name')=“pin”)&(psf.col('type')=“country”))|
((psf.col(‘名称’=‘大陆’)和(psf.col(‘类型’=‘国家’))
,
3.
).什么时候(
(psf.col(‘名称’=‘大陆’)和(psf.col(‘类型’)=‘引脚’),
4.
)。否则(1)
)
df.show(10)
+---------+-------+--------+
|名称|类型|序列|
+---------+-------+--------+
|城市|空| 1|
|州|空| 1|
|乡村|城市| 2|
|国家|州| 2|
|别针|国家| 3|
|引脚|状态| 2|
|大陆|国家| 3|
|大陆|针| 4|
|大陆|城市| 2|
+---------+-------+--------+
当 由于在您的条件中没有明显的模式,我现在建议使用chained
when
或a
join
,除此之外,没有其他方法

其思想是在两列上创建一个给定条件的数据帧,然后将其合并。解决方案未经测试

conditions=spark.createDataFrame([('country','city',2),('Continental','city',2),
('pin','state',2),('country','state',2),
('pin','country',3),('containment','country',3),
("洲","宾",4),,
['name'、'type'、'sequence'])
df=df.连接(psf.广播(条件),
['name','type'],'left_outer')
.fillna(1,子集=['sequence'])
顺便说一下,我使用
psf.broadcast
来加速合并,因为
条件
数据帧
的大小应该合理


如果你有大量的条件,我认为这种方法应该是首选。这将使您的代码更具可读性

是的。从一个艰难的开始!您希望在哪个数据库和版本中执行此操作?是否需要
pyspark̀
解决方案?因为有标签,但你在问题中没有提到任何关于spark的内容,你需要一个递归查询,MySql 8.0就有了它。我需要spark SQL或pyspark或MySQL。我又用一个例子更新了这个问题。帮我解决这个问题,答案是upda