0

我想知道如何在不必两次写出(或使数据库进程)成为该查询的主要部分的情况下做到这一点。

我的场景是我正在查询一个 Oracle 企业数据库(我受到 DBA 的限制,所以有些解决方案可能不起作用,但我不确定我受限到什么程度,直到我尝试并且不知道去哪里还没有)。

目前,我的查询如下所示:

    SELECT
        a.Field1,
        a.Field2,
        b.Field3,
        b.Field4,
        c.Field5
    FROM
        a,
        b,
        c,
    WHERE
            a.FieldX = b.FieldX
        AND
            b.FieldY = c.FieldY

UNION
  (
    SELECT
        d.Field6 as Field1,
        d.Field7 + d.Field8 as Field2,
        MainQuery.Field3,
        MainQuery.Field4,
        MainQuery.Field5
    FROM
        (
            SELECT
                a.Field1,
                a.Field2,
                b.Field3,
                b.Field4,
                c.Field5
            FROM
                a,
                b,
                c,
            WHERE
                    a.FieldX = b.FieldX
                AND
                    b.FieldY = c.FieldY
                AND
                    a.FieldZ = 'XXXX'
        ) MainQuery,

        d
    WHERE
        MainQuery.Field1 = d.Field6
  )

简单地说,我有一个主查询(第一部分),它返回我的大部分结果,然后我重复主查询,但有一个额外的限制(a.FieldZ = 'XXXX'),并从这个查询和第二个表中提取数据并将其附加到使用UNION.

我面临的主要挑战是两个查询之间Field1&的定义发生了Field2变化,所以我不知道如何做一个简单的连接。但我确信必须有一种方法可以实现这一点,而不必让数据库查询相同的数据两次。

关于如何使这个查询更有效的任何想法?

谢谢!!


根据评论,更多地解释这个查询 - 我要做的是在查询的前半部分获取我的全部数据,然后在查询的后半部分附加额外的行以获取记录其中a.FieldZ = 'XXXX'计算与和的略有不同的Field1地方Field2

4

4 回答 4

2

因此,根据您的评论,您的要求似乎是“第 2 列将从表中获取M。另外,当M.fieldZ = 'XXX'需要从表中添加带有字段的额外行时D。”

在这种情况下,您将不得不使用 UNION ALL 或通过加入 2 行表来复制您的记录。您可以使用该WITH子句在 SELECT 中重用子查询。这将使其更具可读性,优化器可能决定只运行一次查询(通过将子查询的结果保存在 temp 中)。

WITH mainquery AS (SELECT /* your main query */)
SELECT *
  FROM mainquery
 UNION ALL
SELECT field1, d.field2 /*, ... */
  FROM (SELECT * FROM mainquery WHERE fieldZ = 'XXX') m
  JOIN d ON m.field1 = d.field6
于 2013-02-21T14:58:38.040 回答
1

我相信这是一种方法,可以为您提供所需的答案。如果没有大量数据,我无法判断它是否会更快。在这里,您将扫描临时表几次,但如果基本查询从表 a、b、c 和 d 中返回一小组数据,则工作量可能会减少。

with foo as 
   (SELECT
        a.Field1,
        a.Field2,
        a.FieldZ,
        b.Field3,
        b.Field4,
        c.Field5
    FROM
        a,
        b,
        c
    WHERE
            a.FieldX = b.FieldX
        AND
            b.FieldY = c.FieldY
)
select Field1
       ,field2
       ,field3
       ,field4
       ,field5 
from foo
union
select
 d.Field6 as Field1
 ,d.Field7 ||'+'|| d.Field8 as Field2
 ,foo.Field3
 ,foo.Field4
 ,foo.Field5
from foo
join d on foo.field1 = d.field6
where foo.fieldz = 'XXXX'
于 2013-02-21T16:43:28.563 回答
0

使用case声明(http://www.techonthenet.com/oracle/functions/case.php

例如

select case when FieldZ = 'XXXX' then Field6 else Field1 end as Field1,
       case when FieldZ = 'XXXX' then Field7 + Field8 else Field2 as Field2,
       Field3,
       Field4,
       Field5
from   a join b on a.FieldX = b.FieldX
       join c on b.FieldY = c.FieldY
       left join d on a.Field1 = d.Field6
于 2013-02-21T14:54:52.920 回答
0

If your intention is not to duplicate the XXXX records, then you can simplify the query to an appropriate join with case statements:

SELECT (case when a.FieldZ = 'XXXX' then a.Field1 else d.Field6 end) as Field1,
       (case when a.FieldZ = 'XXXX' then a.Field2 else d.Field7 + d.Field8 end) as Field2,
        b.Field3,
        b.Field4,
        c.Field5
FROM a join
     b
     on a.FieldX = b.FieldX join
     C
     on b.FieldY = c.FieldY left outer join
     d
     on A.Field1 = d.Field6 and
        a.FieldZ = 'XXXX'

If you are duplicating these records, then some sort of union all would seem necessary.

于 2013-02-21T15:02:50.433 回答