【问题标题】:How to make valid combinations of many separate tables with subcombinations如何使用子组合对许多单独的表进行有效组合
【发布时间】:2019-12-31 17:30:04
【问题描述】:

我遇到了一些我不知道如何理解的 sql 挑战。这就是为什么我希望您的意见能帮助我指导正确的方向以找到解决方案。

我想创建的过程的目标是用有效的值组合填充下表。这些列代表字符串中的六个位置。就像一个有六个单词的句子,只允许使用某种模式。

+------+------+------+------+------+------+
| Pos1 | Pos2 | Pos3 | Pos4 | Pos5 | Pos6 |
+------+------+------+------+------+------+
| AB   | CD   | FS   | KE   | HA   | KA   |
+------+------+------+------+------+------+
| ..   | ..   | ..   | ..   | ..   | ..   |
+------+------+------+------+------+------+ 

当组合的所有位置都针对许多其他表进行验证时,六个位置的组合(模式)是有效的。总共有 30 个表格,其中包含两个位置的有效组合。每个位置组合有两个表。例如:一个包含有效组合 Pos1 To Pos2(从左到右)和一个包含有效组合 Pos2 To Pos1(从右到左)。表格示例:

表A

+------+------+
| Pos1 | Pos2 |
+------+------+
| AB   | CD   |
+------+------+
| AB   | EF   |
+------+------+
| AA   | GG   |
+------+------+

表B

+------+------+
| Pos1 | Pos2 |
+------+------+
| AB   | YT   |
+------+------+
| AA   | YT   |
+------+------+
| AB   | CD   |
+------+------+

表C

+------+------+
| Pos2 | Pos3 |
+------+------+
| CD   | FF   |
+------+------+
| CD   | UE   |
+------+------+
| EF   | KH   |
+------+------+

表D

+------+------+
| Pos2 | Pos3 |
+------+------+
| CD   | FE   |
+------+------+
| CD   | UE   |
+------+------+
| EF   | KY   |
+------+------+

表E

+------+------+
| Pos1 | Pos6 |
+------+------+
| AB   | ZZ   |
+------+------+
| AB   | ZF   |
+------+------+
| AA   | ZT   |
+------+------+

等等……

我知道我可以开始使用 INTERSECT 语句来交叉两个具有相同位置的表之间的所有组合,例如

INSERT INTO TempTable12
( SELECT *
  FROM TableA
  INTERSECT
  SELECT *
  FROM TableB ) Valid12;

INSERT INTO TempTable23
( SELECT *
  FROM TableC
  INTERSECT
  SELECT *
  FROM TableD ) Valid23;

等等……

..但是当我想继续担任两个以上职位时,我该怎么做?换句话说,在查询中组合不同的位置。我应该像上面的例子那样使用临时表吗?有没有更好的方法?

我希望这对您来说不会太神秘,并且仍然可以帮助我入门。提前致谢!

【问题讨论】:

    标签: sql oracle join combinations intersect


    【解决方案1】:

    我将首先创建将获得最终结果的测试数据。首先,CREATE TABLE 语句;然后,在每个表中插入一个。

    create table t12 (pos1 varchar2(2), pos2 varchar2(2));
    create table t21 (pos1 varchar2(2), pos2 varchar2(2));
    create table t13 (pos1 varchar2(2), pos3 varchar2(2));
    create table t31 (pos1 varchar2(2), pos3 varchar2(2));
    create table t14 (pos1 varchar2(2), pos4 varchar2(2));
    create table t41 (pos1 varchar2(2), pos4 varchar2(2));
    create table t15 (pos1 varchar2(2), pos5 varchar2(2));
    create table t51 (pos1 varchar2(2), pos5 varchar2(2));
    create table t16 (pos1 varchar2(2), pos6 varchar2(2));
    create table t61 (pos1 varchar2(2), pos6 varchar2(2));
    create table t23 (pos2 varchar2(2), pos3 varchar2(2));
    create table t32 (pos2 varchar2(2), pos3 varchar2(2));
    create table t24 (pos2 varchar2(2), pos4 varchar2(2));
    create table t42 (pos2 varchar2(2), pos4 varchar2(2));
    create table t25 (pos2 varchar2(2), pos5 varchar2(2));
    create table t52 (pos2 varchar2(2), pos5 varchar2(2));
    create table t26 (pos2 varchar2(2), pos6 varchar2(2));
    create table t62 (pos2 varchar2(2), pos6 varchar2(2));
    create table t34 (pos3 varchar2(2), pos4 varchar2(2));
    create table t43 (pos3 varchar2(2), pos4 varchar2(2));
    create table t35 (pos3 varchar2(2), pos5 varchar2(2));
    create table t53 (pos3 varchar2(2), pos5 varchar2(2));
    create table t36 (pos3 varchar2(2), pos6 varchar2(2));
    create table t63 (pos3 varchar2(2), pos6 varchar2(2));
    create table t45 (pos4 varchar2(2), pos5 varchar2(2));
    create table t54 (pos4 varchar2(2), pos5 varchar2(2));
    create table t46 (pos4 varchar2(2), pos6 varchar2(2));
    create table t64 (pos4 varchar2(2), pos6 varchar2(2));
    create table t56 (pos5 varchar2(2), pos6 varchar2(2));
    create table t65 (pos5 varchar2(2), pos6 varchar2(2));
    
    insert into t12 values('AB', 'CD');
    insert into t21 values('AB', 'CD');
    insert into t13 values('AB', 'FS');
    insert into t31 values('AB', 'FS');
    insert into t14 values('AB', 'KE');
    insert into t41 values('AB', 'KE');
    insert into t15 values('AB', 'HA');
    insert into t51 values('AB', 'HA');
    insert into t16 values('AB', 'KA');
    insert into t61 values('AB', 'KA');
    insert into t23 values('CD', 'FS');
    insert into t32 values('CD', 'FS');
    insert into t24 values('CD', 'KE');
    insert into t42 values('CD', 'KE');
    insert into t25 values('CD', 'HA');
    insert into t52 values('CD', 'HA');
    insert into t26 values('CD', 'KA');
    insert into t62 values('CD', 'KA');
    insert into t34 values('FS', 'KE');
    insert into t43 values('FS', 'KE');
    insert into t35 values('FS', 'HA');
    insert into t53 values('FS', 'HA');
    insert into t36 values('FS', 'KA');
    insert into t63 values('FS', 'KA');
    insert into t45 values('KE', 'HA');
    insert into t54 values('KE', 'HA');
    insert into t46 values('KE', 'KA');
    insert into t64 values('KE', 'KA');
    insert into t56 values('HA', 'KA');
    insert into t65 values('HA', 'KA');
    commit;
    

    现在寻找解决方案。从 INTERSECT 开始,您就走在了正确的轨道上。使用 WITH 子句,您可以列出所有交集子查询并将 30 个表减少到 15 个子查询。之后,您需要开始加入。我在连接中使用了 USING 子句,因为它执行相等连接并合并连接列。

    with q12 as (select * from t12 intersect select * from t21)
    , q13 as (select * from t13 intersect select * from t31)
    , q14 as (select * from t14 intersect select * from t41)
    , q15 as (select * from t15 intersect select * from t51)
    , q16 as (select * from t16 intersect select * from t61)
    , q23 as (select * from t23 intersect select * from t32)
    , q24 as (select * from t24 intersect select * from t42)
    , q25 as (select * from t25 intersect select * from t52)
    , q26 as (select * from t26 intersect select * from t62)
    , q34 as (select * from t34 intersect select * from t43)
    , q35 as (select * from t35 intersect select * from t53)
    , q36 as (select * from t36 intersect select * from t63)
    , q45 as (select * from t45 intersect select * from t54)
    , q46 as (select * from t46 intersect select * from t64)
    , q56 as (select * from t56 intersect select * from t65)
    select pos1, pos2, pos3, pos4, pos5, pos6
    from q12
    join q13 using(pos1)
    join q14 using(pos1)
    join q15 using(pos1)
    join q16 using(pos1)
    join q23 using(pos2, pos3)
    join q24 using(pos2, pos4)
    join q25 using(pos2, pos5)
    join q26 using(pos2, pos6)
    join q34 using(pos3, pos4)
    join q35 using(pos3, pos5)
    join q36 using(pos3, pos6)
    join q45 using(pos4, pos5)
    join q46 using(pos4, pos6)
    join q56 using(pos5, pos6);
    
    POS1 POS2 POS3 POS4 POS5 POS6
    ---- ---- ---- ---- ---- ----
    AB   CD   FS   KE   HA   KA
    

    【讨论】:

      【解决方案2】:

      我认为您可以使用大量 join 来做到这一点。我不完全理解为什么你有 30 个表而不是 15 个,但想法是:

      select tab12.pos1, tab12.pos2, tab13.pos3,
             tab14.pos4, tab15.pos5, tab16.pos6
      from tab12 join
           tab13
           on tab12.pos1 = tab13.pos1 join
           tab14
           on tab12.pos1 = tab14.pos1 join
           tab15
           on tab12.pos1 = tab15.pos1 join
           tab16
           on tab12.pos1 = tab16.pos1
      

      然后使用existsin 或进一步joins 过滤这些其他条件:

      select tab12.pos1, tab12.pos2, tab13.pos3,
             tab14.pos4, tab15.pos5, tab16.pos6
      from tab12 join
           tab13
           on tab12.pos1 = tab13.pos1 join
           tab14
           on tab12.pos1 = tab14.pos1 join
           tab15
           on tab12.pos1 = tab15.pos1 join
           tab16
           on tab12.pos1 = tab16.pos1 join
           tab23
           on tab23.pos2 = tab12.pos2 and
              tab23.pos3 = tab13.pos3 join
           tab23
           on tab24.pos2 = tab12.pos2 and
              tab24.pos3 = tab14.pos4 join
           . . . 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        相关资源
        最近更新 更多