使用通配符的复杂和自定义SQL连接条件

时间:2018-08-15 19:39:42

标签: python mysql sql join hive

我有两个表,一个小(〜6K行),另一个大(〜3M行)

表一看起来像

## Table 1
-----------------------------------
| colA | colB | colC | ... | colZ |
-----------------------------------
| vA_1 |  *   | vC_1 | ... |  *   |
|  *   |  *   | vC_1 | ... | vZ_1 |
| vA_2 | vB_1 | vC_2 | ... | vZ_2 |
...

表二看起来像

## Table 2
-----------------------------------------
| colA | colB | colC | ... | colZ | ... |
-----------------------------------------
| vA_1 | vB_1 | vC_1 | ... | vZ_1 | ... |
| vA_1 | vB_1 | vC_2 | ... | vZ_2 | ... |
| vA_2 | vB_2 | vC_3 | ... | vZ_2 | ... |
...

因此,我们希望基于所有列colA,colB,...,colZ将两个表“连接”在一起,其中通配符(*)将匹配任何内容。例如,对于表一的第一行。

-----------------------------------
| colA | colB | colC | ... | colZ |
-----------------------------------
| vA_1 |  *   | vC_1 | ... |  *   |

它应该只能匹配表2中的第一行,因为colA和colC是匹配的,并且其他任何列都可以是任何值,如第一表中的通配符所示。

## Table 2
-----------------------------------------
| colA | colB | colC | ... | colZ | ... |
-----------------------------------------
| vA_1 | vB_1 | vC_1 | ... | vZ_1 | ... |  √
| vA_1 | vB_1 | vC_2 | ... | vZ_2 | ... |  X
| vA_2 | vB_2 | vC_3 | ... | vZ_2 | ... |  X 
...

我们想构建一些动态可选联接,例如

if colA is *
    then join on colB, colC, ..
if colB is * 
    then join on colA, colC, ..
if colA is * and colB is *
    then join on colC, ...
...

我们意识到,随着列数的增加,条件可以呈指数增长(几乎所有组合都是阶乘)。因此,我想知道SQL中是否有解决方案可以处理这种联接。

我也愿意接受其他解决方案,例如Python或MapReduce,Spark中的自定义代码。

2 个答案:

答案 0 :(得分:1)

这很长JOIN,但我想它会起作用:

select t1.*, t2.*
  from table1 t1
  join table2 t2
     on (t1.cola = '*' or t1.cola = t2.cola)
    and (t1.colb = '*' or t1.colb = t2.colb)
    ...    
    and (t1.colz = '*' or t1.colz = t2.colz)

如果表2中有通配符*,则查询会变得更加复杂:

select t1.*, t2.*
  from table1 t1
  join table2 t2
     on (t1.cola = '*' or t2.cola = '*' or t1.cola = t2.cola)
    and (t1.colb = '*' or t2.colb = '*' or t1.colb = t2.colb)
    ...    
    and (t1.colz = '*' or t2.colz = '*' or t1.colz = t2.colz)

答案 1 :(得分:1)

这样的事情可以满足您的需求吗?

SELECT *
       FROM table1 t1
            INNER JOIN table2 t2
                       ON (t2.cola = t1.cola
                            OR t1.cola = '*')
                          AND (t2.colb = t1.colb
                                OR t1.colb = '*')
                          ...
                          AND (t2.colz = t1.colz
                                OR t1.colz = '*');

(假设示例数据中没有NULL,如果有<a href="javascript: w=window.open('https://mywebsite.com/print/f47aea8bdcbd1179a1f3d91e6afeeb259488f2d1'); w.print();" class="btn btn-primary btn"> <i class="icon-print"></i> <span class="hidden-xs">Print</span> ,则根据您在此情况下定义为匹配项的不同,可能需要对其进行特殊处理。)