SQL多对多连接,当存在匹配项时排除不匹配的行

问题描述 投票:0回答:1

我有两个表,每个季度都有一个数据。每个刻钟可以有多个观察结果。我想做的是将这些表连接在一起,使观察值匹配的所有行和观察值不匹配的行同时也存在匹配时不显示不匹配。

例如:

enter image description here

表A:

+-----+----------------+---------------+
| key |      qhr       | observation_A |
+-----+----------------+---------------+
|   1 | 1/1/2020 10:00 | A             |
|   1 | 1/1/2020 10:00 | B             |
|   1 | 1/1/2020 10:15 | A             |
|   1 | 1/1/2020 10:15 | B             |
|   1 | 1/1/2020 10:30 | B             |
|   1 | 1/1/2020 10:45 | A             |
|   1 | 1/1/2020 11:00 | B             |
|   1 | 1/1/2020 11:00 | C             |
|   1 | 1/1/2020 11:15 | C             |
|   2 | 1/1/2020 10:00 | C             |
|   2 | 1/1/2020 10:00 | B             |
|   2 | 1/1/2020 10:15 | A             |
|   2 | 1/1/2020 10:15 | C             |
|   2 | 1/1/2020 10:30 | A             |
|   2 | 1/1/2020 10:45 | C             |
|   2 | 1/1/2020 11:00 | A             |
|   2 | 1/1/2020 11:00 | C             |
|   2 | 1/1/2020 11:15 | B             |
+-----+----------------+---------------+

表B:

+-----+----------------+---------------+
| key |      qhr       | observation_B |
+-----+----------------+---------------+
|   1 | 1/1/2020 10:00 | A             |
|   1 | 1/1/2020 10:00 | B             |
|   1 | 1/1/2020 10:15 | A             |
|   1 | 1/1/2020 10:15 | C             |
|   1 | 1/1/2020 10:30 | B             |
|   1 | 1/1/2020 10:45 | A             |
|   1 | 1/1/2020 11:00 | A             |
|   1 | 1/1/2020 11:00 | C             |
|   1 | 1/1/2020 11:15 | C             |
|   2 | 1/1/2020 10:00 | C             |
|   2 | 1/1/2020 10:00 | B             |
|   2 | 1/1/2020 10:15 | A             |
|   2 | 1/1/2020 10:15 | C             |
|   2 | 1/1/2020 10:30 | B             |
|   2 | 1/1/2020 10:45 | C             |
|   2 | 1/1/2020 11:00 | A             |
|   2 | 1/1/2020 11:15 | A             |
+-----+----------------+---------------+

预期输出:

+-----+----------------+---------------+---------------+-------+
| key |      qhr       | observation_A | observation_B | MATCH |
+-----+----------------+---------------+---------------+-------+
|   1 | 1/1/2020 10:00 | A             | A             | Y     |
|   1 | 1/1/2020 10:00 | B             | B             | Y     |
|   1 | 1/1/2020 10:15 | A             | A             | Y     |
|   1 | 1/1/2020 10:15 | B             | C             | N     |
|   1 | 1/1/2020 10:30 | B             | B             | Y     |
|   1 | 1/1/2020 10:45 | A             | A             | Y     |
|   1 | 1/1/2020 11:00 | B             | A             | N     |
|   1 | 1/1/2020 11:00 | C             | C             | Y     |
|   1 | 1/1/2020 11:15 | C             | C             | Y     |
|   2 | 1/1/2020 10:00 | C             | C             | Y     |
|   2 | 1/1/2020 10:00 | B             | B             | Y     |
|   2 | 1/1/2020 10:15 | A             | A             | Y     |
|   2 | 1/1/2020 10:15 | C             | C             | Y     |
|   2 | 1/1/2020 10:30 | A             | B             | N     |
|   2 | 1/1/2020 10:45 | C             | C             | Y     |
|   2 | 1/1/2020 11:00 | A             | A             | Y     |
|   2 | 1/1/2020 11:00 | C             |               | N     |
|   2 | 1/1/2020 11:15 | B             | A             | N     |
+-----+----------------+---------------+---------------+-------+

[我尝试使用完全外部联接来包含观察值不匹配的时间,但是当我这样做时,即使存在像这样的匹配,我也能获得所有组合的潜力:

+-----+----------------+---------------+---------------+-------+
| key |      qhr       | observation_A | observation_B | MATCH |
+-----+----------------+---------------+---------------+-------+
|   1 | 1/1/2020 10:00 | A             | B             | N     |
|   1 | 1/1/2020 10:00 | A             | A             | Y     |
|   1 | 1/1/2020 10:00 | B             | B             | Y     |
|   1 | 1/1/2020 10:00 | B             | A             | N     |
+-----+----------------+---------------+---------------+-------+

我试图找出一种方法来包括任何合法的不匹配项,但排除行1和4,因为A和B实际上是匹配的。

我正在spark中工作,因此我可以使用spark SQL或pyspark数据帧来解决此问题,甚至可能解决熊猫问题。任何建议,将不胜感激。

pandas pyspark pyspark-sql
1个回答
0
投票

将日期强制转换为日期时间,提取分钟并将其转换回对象类型

df4['qhr']=pd.to_datetime(df4['qhr']).dt.minute.astype('object')
df1['qhr']=pd.to_datetime(df1['qhr']).dt.minute.astype('object')

在key和qhr列上执行外部联接。与内部,左侧等相比,外部联接保留所有联接数据框属性中的所有属性]

merged_df = df4.merge(df1, how = 'outer', on = ['key', 'qhr'],  suffixes=('_A', '_B'))

使用np.where检查和属性条件

merged_df['Match']= np.where(merged_df['obs_A'] == merged_df['obs_B'], 'Y', 'N')
© www.soinside.com 2019 - 2024. All rights reserved.