特定的交叉连接查询

时间:2012-03-28 08:25:34

标签: sql oracle

获得表A,B和C.所有表都有主键。表B和C都有字段id_a,它是表A的键的链接。 我想编写一个select语句,它将选择表A中的所有行,表C中的一列和B中的一列。但它们必须像2个独立列一样连接。因此,对于表A中的一个键,必须有max(B,C)行,其中包含来自A的所有数据加上这2个列,例如:

------------------
a11....a1n|b11|c11
a11....a1n|b12|c12
a11....a1n|b13|null
a11....a1n|b14|null
a21....a2n|b21|c21
a21....a2n|b22|c22
a21....a2n|null|c23
a21....a2n|null|c24
a21....a2n|null|c25

{bXY}表示它是来自B的值,链接到来自a的值X,而Y只是枚举

当然,表B和C中的所有值必须通过其id_a字段对应于表A.

表格结构:

Table A:
id int autoincrement
name varchar 

Table B:
id int autoincrement
id_a int 
value_b float

Table C:
id int autoincrement
id_a int
value_c int

2 个答案:

答案 0 :(得分:3)

如果为包含较少行的表生成空行,则可以执行此操作。 B和C中的每一行都分配了一个数字。全外连接会添加缺少的行。

select a.*, value_b, value_c
from TableA a
left join
(
   select nvl(b.id_a, c.id_a) AS id_a, b.value_b, c.value_c
     from 
     (
        select b.id_a, b.value_b,
               row_number() over (partition by b.id_a order by b.id) rn
          from TableB b
     ) b
     full outer join
     (
        select c.id_a, c.value_c,
               row_number() over (partition by c.id_a order by c.id) rn
          from TableC c
     ) c
       on b.id_a = c.id_a
      and b.rn = c.rn
) maxRows
  on a.id = maxRows.id_a

您可以在Sql Fiddle

查看

答案 1 :(得分:-1)

您可以尝试以下操作:(基于SQLServer而不是Oracle)

declare @AValues varchar(max)
select @AValues = ISNULL(@AValues,'')+ a.A_column + ',' from tableA a

select A_PrimaryKey, @AValues, b.B_column, c.C_column from
(
  select b.id_a A_PrimaryKey from tableB b
  union
  select c.id_a A_PrimaryKey from tableC c
) x
left join tableB b on b.id_a = x.A_PrimaryKey
left join tableC c on c.id_a = x.A_PrimaryKey

为了进一步改进,您可以通过SQL子查询替换变量@AValues,该子查询将TableA中的所有行作为逗号分隔列表返回。

TableB和TableC之间的联合将为您提供您感兴趣的TableA的所有主键值,实际上是TableB和TableC中的最大行数。左连接将为您提供TableB或TableC中的值。

希望这在某种程度上有所帮助!