Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将子选择转换为联接_Sql_Db2 400 - Fatal编程技术网

Sql 将子选择转换为联接

Sql 将子选择转换为联接,sql,db2-400,Sql,Db2 400,我似乎明白,Join比sub-select更受欢迎。 我看不出如何将3个子选择变成连接 我的sub选择仅获取第一行 如果这不是冒犯性的SQL,我完全愿意就此置之不理 这是我的查询,是的,这些确实是表名和列名 select x1.*, x2.KTNR, x3.J6NQ from (select D0HONB as HONB, D0HHNB as HHNB, ( select DHHHNB from ECDHREP

我似乎明白,Join比sub-select更受欢迎。 我看不出如何将3个子选择变成连接

我的sub选择仅获取第一行

如果这不是冒犯性的SQL,我完全愿意就此置之不理

这是我的查询,是的,这些确实是表名和列名

select x1.*, x2.KTNR, x3.J6NQ
from 
    (select D0HONB as HONB, D0HHNB as HHNB, 
        (
            select DHHHNB 
            from ECDHREP 
            where DHAOEQ = D0ATEQ and DHJRCD = D0KNCD 
            order by DHEJDT desc 
            FETCH FIRST 1 ROW ONLY
        ) as STC_HHNB,
        (
            select FIQ9NB 
            from DCFIREP 
            where FIQ7NB = D0Q7NB 
              AND FIBAEQ = D0ATEQ 
              and FISQCD = D0KNCD 
              and FIGZSZ in ('POS', 'ACT', 'MAN', 'HLD') 
            order by FIYCNB desc 
            FETCH FIRST 1 ROW ONLY
        ) as BL_Q9NB,
        (
            select AAKPNR 
            from C1AACPP 
            where AACEEQ = D0ATEQ and AARCCE = D0KNCD and AARDCE = D0KOCD 
            order by AAHMDT desc, AANENO desc 
            FETCH FIRST 1 ROW ONLY 
        ) as NULL_KPNR  
        from ECD0REP
    ) as x1 
left outer join (
        select AAKPNR as null_kpnr, max(ABKTNR) as KTNR 
        from C1AACPP 
          left outer join C1ABCPP on AAKPNR = ABKPNR 
        group by AAKPNR
    ) as X2 on x1.NULL_KPNR = x2.null_KPNR 
left outer join (
        select ACKPNR as KPNR, count(*) as J6NQ 
        from C1ACCPP 
        WHERE ACJNDD = 'Y' 
        group by ACKPNR
    ) as X3 on x1.NULL_KPNR = x3.KPNR 

您已经获得了相关子选择和嵌套表表达式(NTE)的组合

就我个人而言,如果我不得不维持它,我会称之为冒犯

考虑常见的表表达式和联接……如果没有数据和tabvle结构,我无法给出真正的语句,但一般形式如下

with 
   STC_HHNB as (
     select DHHHNB, DHAOEQ, DHJRCD, DHEJDT
      from ECDHREP )
,  BL_Q9NB as ( <....>
               where FIGZSZ in ('POS', 'ACT', 'MAN', 'HLD'))
<...>
select <...>
from stc_hhb
     join blq9nb on <...>
您要求DB做的是针对ECD0REP中读取的每一行,从ECDHREP中获取一行。如果您运气不好,数据库将不得不读取ECDHREP中的大量记录才能找到那一行。一般来说,考虑到相关的子查询,内部查询将需要读取<强>每个< /强>行。因此,如果外部有M行,内部有N行……那么您看到的是正在读取的MxN行

我以前见过这种情况,尤其是在IBMi上。因为这是一个RPG开发者应该做的

read ECD0REP;
dow not %eof(ECD0REP);
  //need to get DHHHNB from ECDHREP 
  chain (D0ATEQ, D0KNCD) ECDHREP;
  STC_HHNB = DHHHNB;
  read ECD0REP;
enddo;
但在SQL中这不是实现它的方法。SQL是(应该是)基于集合的

因此,您需要做的是考虑如何从ECDHREP中选择与您想要从ECD0REP中获得的记录集相匹配的记录集

with cte1 as (
  select DHHHNB, DHAOEQ, DHJRCD
  from ECDHREP
)
select D0HONB as HONB
     , D0HHNB as HHNB
     , DHHHBN as STC_HHNB
from ECD0REP join cte1 
      on DHAOEQ = D0ATEQ and DHJRCD = D0KNCD
也许这不太正确。也许ECDHREP中有多行具有相同的值(DHAOEQ、DHJRCD);因此,您需要在相关子查询中首先获取
FETCH
。好的,你可以专注于CTE,找出需要做什么才能得到你想要的那一行。也许
MAX(DHHHNB)
MIN(DHHHNB)
会起作用。如果没有其他内容,您可以使用
行数()

with cte1 as (
  select DHHHNB, DHAOEQ, DHJRCD
         , row_number() over(partition by DHAOEQ, DHJRCD
                             order by DHAOEQ, DHJRCD)
            as rowNbr  
  from ECDHREP
), cte2 as (
   select DHHHNB, DHAOEQ, DHJRCD
     from cte1
    where rowNbr = 1
)
select D0HONB as HONB
     , D0HHNB as HHNB
     , DHHHBN as STC_HHNB
from ECD0REP join cte2
      on DHAOEQ = D0ATEQ and DHJRCD = D0KNCD
现在,您正在处理一组记录,将它们连接在一起以获得最终结果

更糟糕的情况是,数据库必须读取M+N个记录

这不是关于表演,而是关于成套思维

当然,通过使用相关子查询的简单语句,优化器可能能够将其重新写入联接

但最好是尽可能编写最好的代码,而不是希望优化器能够纠正它


我看到并重写了100个相关和常规子查询的查询……事实上,我看到一个查询必须分成两个,因为有两个多个子查询。DB对每条语句的限制为256条。

您得到了相关子选择和嵌套表表达式(NTE)的组合

就我个人而言,如果我不得不维持它,我会称之为冒犯

考虑常见的表表达式和联接……如果没有数据和tabvle结构,我无法给出真正的语句,但一般形式如下

with 
   STC_HHNB as (
     select DHHHNB, DHAOEQ, DHJRCD, DHEJDT
      from ECDHREP )
,  BL_Q9NB as ( <....>
               where FIGZSZ in ('POS', 'ACT', 'MAN', 'HLD'))
<...>
select <...>
from stc_hhb
     join blq9nb on <...>
您要求DB做的是针对ECD0REP中读取的每一行,从ECDHREP中获取一行。如果您运气不好,数据库将不得不读取ECDHREP中的大量记录才能找到那一行。一般来说,考虑到相关的子查询,内部查询将需要读取<强>每个< /强>行。因此,如果外部有M行,内部有N行……那么您看到的是正在读取的MxN行

我以前见过这种情况,尤其是在IBMi上。因为这是一个RPG开发者应该做的

read ECD0REP;
dow not %eof(ECD0REP);
  //need to get DHHHNB from ECDHREP 
  chain (D0ATEQ, D0KNCD) ECDHREP;
  STC_HHNB = DHHHNB;
  read ECD0REP;
enddo;
但在SQL中这不是实现它的方法。SQL是(应该是)基于集合的

因此,您需要做的是考虑如何从ECDHREP中选择与您想要从ECD0REP中获得的记录集相匹配的记录集

with cte1 as (
  select DHHHNB, DHAOEQ, DHJRCD
  from ECDHREP
)
select D0HONB as HONB
     , D0HHNB as HHNB
     , DHHHBN as STC_HHNB
from ECD0REP join cte1 
      on DHAOEQ = D0ATEQ and DHJRCD = D0KNCD
也许这不太正确。也许ECDHREP中有多行具有相同的值(DHAOEQ、DHJRCD);因此,您需要在相关子查询中首先获取
FETCH
。好的,你可以专注于CTE,找出需要做什么才能得到你想要的那一行。也许
MAX(DHHHNB)
MIN(DHHHNB)
会起作用。如果没有其他内容,您可以使用
行数()

with cte1 as (
  select DHHHNB, DHAOEQ, DHJRCD
         , row_number() over(partition by DHAOEQ, DHJRCD
                             order by DHAOEQ, DHJRCD)
            as rowNbr  
  from ECDHREP
), cte2 as (
   select DHHHNB, DHAOEQ, DHJRCD
     from cte1
    where rowNbr = 1
)
select D0HONB as HONB
     , D0HHNB as HHNB
     , DHHHBN as STC_HHNB
from ECD0REP join cte2
      on DHAOEQ = D0ATEQ and DHJRCD = D0KNCD
现在,您正在处理一组记录,将它们连接在一起以获得最终结果

更糟糕的情况是,数据库必须读取M+N个记录

这不是关于表演,而是关于成套思维

当然,通过使用相关子查询的简单语句,优化器可能能够将其重新写入联接

但最好是尽可能编写最好的代码,而不是希望优化器能够纠正它


我看到并重写了100个相关和常规子查询的查询……事实上,我看到一个查询必须分成两个,因为有两个多个子查询。DB对每条语句的限制为256。

如果需要
仅获取第一行
子句,我将不得不在这里与Charles不同。在这种情况下,您可能无法将这些子选项拉到CTE中,因为该CTE中只有一行。我怀疑您可以将外部子选择拉入CTE,但您仍然需要CTE中的子选择。既然没有分享,我就称之为个人偏好。顺便说一句,出于同样的原因,我认为将子选择拉入联接也不适用于您

子选择和CTE之间有什么区别

with mycte as (
  select field1, field2 
  from mytable
  where somecondition = true)
select * 
from mycte
vs

这实际上只是个人偏好,尽管根据具体要求,CTE可以在SQL语句中多次使用,但在其他情况下,如问题中的
fetch FIRST
子句,子选择将更为正确

编辑
让我们看一下第一个子查询。使用适当的索引:

(
    select DHHHNB 
    from ECDHREP 
    where DHAOEQ = D0ATEQ and DHJRCD = D0KNCD 
    order by DHEJDT desc 
    FETCH FIRST 1 ROW ONLY
) as STC_HHNB,
输出集中每行只需读取一条记录。我不认为这是非常繁重的。第三个相关子查询也是如此

第一个相关子查询上的索引为:

create index ECDHREP_X1 
  on ECDHREP (DHAOEQ, DHJRCD, DHEJDT);
塞科