如何优化和组合两个SQL查询

时间:2016-10-07 10:48:17

标签: sql

我有两个SQL查询。首先是针对这些智商,' SM',' T2'其次是 pl =' AT',' VV'' CM'。我收到以下信息 -

enter image description here

是否有任何选项可以优化这两个查询并将它们合并为一个? CASE语句中的信息是可重复的,只有pl不同。

首先查询:

/* Formatted on 10.7.2016 1:23:06  (QP5 v5.163.1008.3004) */
SELECT DISTINCT
       pl,
       SUM (
          CASE
             WHEN pl IN ('IQ', 'SM', 'T2')
             THEN
                CASE
                   WHEN time LIKE '201601%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.27131)
                   WHEN time LIKE '201602%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.27609)
                   WHEN time LIKE '201603%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.263019)
                   WHEN time LIKE '201604%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.251591)
                   WHEN time LIKE '201605%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.248002)
                   WHEN time LIKE '201606%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.252972)
                   WHEN time LIKE '201607%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.248432)
                   WHEN time LIKE '201608%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.25790)
                   WHEN time LIKE '201609%'
                   THEN
                      ( (charge / POWER (10, decimals)) * 1.240378)
                   ELSE
                      0
                END
             ELSE
                0
          END)
       OVER ()
          AS charge
  FROM ch
 WHERE     TYPE = 'MO'
       AND pl IN ('IQ', 'SM', 'T2')
       AND time BETWEEN '20160101000000' AND '20160930235959'

第二次查询:

/* Formatted on 10.7.2016 1:36:11  (QP5 v5.163.1008.3004) */
SELECT DISTINCT
   pl,
   SUM (
      CASE
         WHEN pl IN ('AT', 'VV', 'CM')
         THEN
            CASE
               WHEN time LIKE '201601%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.27131)
               WHEN time LIKE '201602%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.27609)
               WHEN time LIKE '201603%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.263019)
               WHEN time LIKE '201604%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.251591)
               WHEN time LIKE '201605%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.248002)
               WHEN time LIKE '201606%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.252972)
               WHEN time LIKE '201607%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.248432)
               WHEN time LIKE '201608%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.25790)
               WHEN time LIKE '201609%'
               THEN
                  ( (charge / POWER (10, decimals)) * 1.240378)
               ELSE
                  0
            END
         ELSE
            0
      END)
   OVER ()
      AS charge
FROM ch
WHERE     TYPE = 'MO'
   AND pl IN ('AT', 'VV', 'CM')
   AND time BETWEEN '20160101000000' AND '20160930235959'

感谢您提前为您提供的帮助

4 个答案:

答案 0 :(得分:1)

您似乎想要union all

with q1 as (
      <first query here>
     ),
     q2 as (
      <second query here>
     )
select q1.*
from q1
union all
select q2.*
from q2;

答案 1 :(得分:1)

您可以在两个查询之间粘贴UNION ALL以组合它们。为了帮助您进行优化,我需要更多信息,例如表结构,索引等。

答案 2 :(得分:0)

如果您的查询在select语句中具有相同的字段名称,则可以使用&#34; UNION&#34;。 很简单是,

select id,name from table1 where condition
Union
select id,name from table2 where condition

这将为您提供两个查询的组合结果。

答案 3 :(得分:0)

如前所述,您似乎将日期时间存储为字符串,这很奇怪。但无论如何:

您的查询从表中选择相同的类型和时间范围,只考虑一组PL而另一组考虑另一组。他们甚至在您的select子句中使用相同的公式。所以这很容易组合

with factors as
(
  select '201601%' as pattern, 1.27131 as factor
  union all
  select '201602%' as pattern, 1.27609 as factor
  union all
  select '201603%' as pattern, 1.263019 as factor
  union all
  select '201604%' as pattern, 1.251591 as factor
  union all
  select '201605%' as pattern, 1.248002 as factor
  union all
  select '201606%' as pattern, 1.252972 as factor
  union all
  select '201607%' as pattern, 1.248432 as factor
  union all
  select '201608%' as pattern, 1.25790 as factor
  union all
  select '201609%' as pattern, 1.240378 as factor
)
select pl, sum(charge) over 
            (partition by case when pl in ('IQ', 'SM', 'T2') then 1 else 2 end) as charge
from
(
  select
    pl,
    sum(case when f.factor is null then 0 
             else ch.charge / power(10, ch.decimals) * f.factor end) as charge
  from ch
  left join factors f on ch.time like f.pattern
  where type = 'MO'
  and time BETWEEN '20160101000000' AND '20160930235959'
  and pl in ('IQ', 'SM', 'T2', 'AT', 'VV', 'CM')
  group by pl
) pls;

您甚至可以在没有子查询的情况下执行此操作。选择你觉得更具可读性的东西。

select
  pl,
  sum
  (
    sum(case when f.factor is null then 0 
             else ch.charge / power(10, ch.decimals) * f.factor end)
  ) over (partition by case when pl in ('IQ', 'SM', 'T2') then 1 else 2 end) as charge
from ch
left join factors f on ch.time like f.pattern
where type = 'MO'
and time BETWEEN '20160101000000' AND '20160930235959'
and pl in ('IQ', 'SM', 'T2', 'AT', 'VV', 'CM')
group by pl;

您可能想要为因子创建一个表,因此您将摆脱with子句。