Oracle中联合的替代方案

时间:2016-06-29 11:00:57

标签: sql oracle

有没有其他方法可以在不使用union的情况下获取以下数据?

select A.name,A.age,B.Address,C.phoneNo from table1 A,Table2 B,Table3 C where a.pkId = b.FkId and b.pkId = c.FkId
union
select A.name,A.age,B.Address,C.phoneNo from table4 A,Table5 B,Table3 C where a.pkId = b.FkId and b.pkId = c.FkId

我在Hibernate中使用它,不幸的是hibernate不支持Union。我只是想知道是否有任何其他方法来实现它,否则不得不在一个过程中写入它并将数据保存在临时表中并触发一个sql来从该临时表中读取数据

3 个答案:

答案 0 :(得分:1)

union有另一种选择,但它并不漂亮:

select distinct coalesce(x1.name, x2.name) as name,
       coalesce(x1.age, x2.age) as age,
       coalesce(x1.Address, x2.Address) as age,
       coalesce(x1.phoneNo, x2.phoneNo) as age,
from (select A.name, A.age, B.Address, C.phoneNo
      from table1 A join
           Table2 B
           on a.pkId = b.FkId join
           Table3 C 
           on b.pkId = c.FkId
     ) x1 full outer join
     (select A.name, A.age, B.Address, C.phoneNo
      from table4 A join
           Table5 B
           on a.pkId = b.FkId join
           Table3 C 
           on b.pkId = c.FkId
     ) x2
     on 1 = 0;  -- always false

我无法想象你为什么要这样表达union。不过,我强烈建议您开始使用正确的join语法。

答案 1 :(得分:0)

这有用吗?

SELECT
    CASE DISTINCT_FLG WHEN 1 THEN nameA ELSE nameB END name,
    CASE DISTINCT_FLG WHEN 1 THEN ageA ELSE ageB END age,
    CASE DISTINCT_FLG WHEN 1 THEN AddressA ELSE AddressB END Address,
    CASE DISTINCT_FLG WHEN 1 THEN phoneNoA ELSE phoneNoB END phoneNo
FROM (
    SELECT
        T1.name AS nameA, T1.age AS ageA, T2.Address AS AddressA, T3.phoneNo AS phoneNoA,
        T4.name AS nameB, T4.age AS ageB, T5.Address AS AddressB, T3.phoneNo AS phoneNoB,
        ROW_NUMBER() OVER(PARTITION BY T1.name, T1.age, T2.Address, T4.name, T4.age, T5.Address, T3.phoneNo ORDER BY NULL) AS DISTINCT_FLG
    FROM
        table1 T1,
        table2 T2,
        table4 T4,
        table5 T5,
        table3 T3
    WHERE
        T1.pkId = T2.FkId AND
        T4.pkId = T5.FkId AND
        (
            T2.pkId = T3.FkId OR
            T5.pkId = T3.FkId
        )
) WHERE DISTINCT_FLG IN (1, 2)

答案 2 :(得分:0)

这两个UNION部分共有Table3 C个,所以我们可以将其余部分加入其中。从源表模拟UNION记录可以通过辅助表与所需数量或行的无条件交叉连接进行复制:

Select Distinct
    CASE R.r WHEN 1 THEN A1.name    ELSE A2.name    END As name   ,
    CASE R.r WHEN 1 THEN A1.age     ELSE A2.age     END As age    ,
    CASE R.r WHEN 1 THEN B1.Address ELSE B2.Address END As Address,
    C.phoneNo
From Table3 C,                                          --< Start at common Table3
  (Select Rownum r From USER_TABLES Where Rownum < 3) R --< Two rows to replicate Table3 C
--   Any table with more than one row will do
--   USER_TABLES should have enough rows in this particular case
Left Join Table2 B1 On R.r = 1 AND B1.pkId = C.FkId     --< Left Join branch one
Left Join table1 A1 On R.r = 1 AND A1.pkId = B1.FkId
Left Join Table5 B2 On R.r = 2 AND B2.pkId = C.FkId     --< Left Join branch two
Left Join table4 A2 On R.r = 2 AND A2.pkId = B2.FkId
Where (R.r = 1 AND A1.pkId Is NOT NULL)                 --/ Make sure we have values
   OR (R.r = 2 AND A2.pkId Is NOT NULL)                 --\ for the branch

但实际上,请考虑view