【问题标题】:Trouble Combining two SELECT Statements组合两个 SELECT 语句时遇到问题
【发布时间】:2012-11-08 18:17:41
【问题描述】:

我确信有一些简单的解决方法。我基本上没有编写 SQL 语句的经验,所以我不知道所有的命令、技巧或语法来获得我需要的东西。

我需要合并以下两条 SQL SELECT 语句:

1:

SELECT 
    h.jhhold, h.jhjob, h.jhrev, o.jadesc, o.jaoqty, o.jacqty, o.japo, o.javend  
FROM 
    Jhead AS h  
LEFT JOIN 
    jjops AS o ON h.jhjob = o.jajob  
WHERE 
    h.jhpcmp = 0 
    AND o.jatype = 2 
    AND o.jacqty < o.jaoqty 
    AND o.japcmp = 0 
    AND o.japo = 0  

2:

SELECT 
    h.jhhold, h.jhjob, h.jhrev, o.jadesc, o.jaoqty, o.jacqty, o.japo, o.javend, 
    p.hdprcd, p.hdrecd, p.hdseq  
FROM 
    Jhead AS h 
LEFT JOIN 
    jjops AS o ON h.jhjob = o.jajob   
LEFT JOIN 
    hpodt AS p ON h.jhjob = p.hdjob   
WHERE 
    h.jhpcmp = 0 
    AND o.jatype = 2 
    AND o.jacqty < o.jaoqty 
    AND o.japcmp = 0 
    AND p.hdjob = h.jhjob 
    AND p.hdpo = o.japo 
    AND p.hdseq = o.jaseq

这两个语句都返回了我需要的结果。第一条语句基本上返回 o.japo = 0 的结果(它永远不会为空)。第二个返回 o.japo 不为零的结果,然后我尝试将另一个表加入数据。我确实尝试在两者之间添加一个 UNION ALL,但我查找的所有联合示例都没有每个 select 语句的 unqiue WHERE 语句。

.
我最初尝试了以下语句(如下),但是当 o.japo = 0 时得到多行数据,我无法弄清楚为什么它会拾取额外的行,但我怀疑这是第二个左连接加入不正确/不需要数据。当 o.japo = 0 时,所有 hpodt (p.) 字段都应该为空,而是填充了来自某个地方的数据。

SELECT h.jhhold, h.jhjob, h.jhrev, o.jadesc, o.jaoqty, o.jacqty, o.japo, o.javend, p.hdprcd, p.hdrecd, p.hdseq 
FROM Jhead AS h 
LEFT JOIN jjops AS o ON h.jhjob = o.jajob 
LEFT JOIN hpodt AS p ON h.jhjob = p.hdjob 
WHERE (h.jhpcmp = 0 AND o.jatype = 2 AND o.jacqty < o.jaoqty AND o.japcmp = 0 AND p.hdjob = h.jhjob AND o.japo != 0 AND p.hdpo = o.japo AND p.hdseq = o.jaseq AND o.jaopr != 'PT') OR (h.jhpcmp = 0 AND o.jatype = 2 AND o.jacqty < o.jaoqty AND o.japcmp = 0 AND o.japo = 0 AND o.jaopr != 'PT')
ORDER BY h.jhjob, o.jaseq, p.hdrecd

【问题讨论】:

    标签: sql select


    【解决方案1】:

    在两个语句之间放置一个UNION

    UNION 需要具有相同数量的列,因此您需要做一些额外的工作。

    在第一个 select 语句中添加一些 null 以覆盖不存在的列。

    SELECT 
       -- Common to both tables
       h.jhhold, h.jhjob, h.jhrev, 
       o.jadesc, o.jaoqty, o.jacqty, 
       o.japo, o.javend, 
       -- These columns don't exist here.
       -- include them anyway as NULL
       NULL as hdprcd,
       NULL AS hdrecd, 
       NULL AS hdseq  
    FROM Jhead AS h  
    LEFT JOIN 
      jjops AS o ON h.jhjob = o.jajob  
    WHERE 
        h.jhpcmp = 0 
    AND o.jatype = 2 
    AND o.jacqty < o.jaoqty 
    AND o.japcmp = 0 
    AND o.japo = 0
    -- The big boy, combining the results of two queries
    ---
    UNION
    SELECT 
       h.jhhold, h.jhjob, h.jhrev, 
       o.jadesc, o.jaoqty, o.jacqty, 
       o.japo, o.javend, p.hdprcd, 
       p.hdrecd, p.hdseq  
    FROM Jhead AS h 
    LEFT JOIN 
       jjops AS o 
    ON h.jhjob = o.jajob   
    LEFT JOIN 
       hpodt AS p 
    ON h.jhjob = p.hdjob   
    WHERE 
        h.jhpcmp = 0 
    AND o.jatype = 2 
    AND o.jacqty < o.jaoqty 
    AND o.japcmp = 0 
    AND p.hdjob = h.jhjob 
    AND p.hdpo = o.japo 
    AND p.hdseq = o.jaseq
    

    【讨论】:

    • 谨慎使用UNION - 它会排序并删除重复的行。 UNION ALL 在这里会更好。
    • 我认为这是这里的意图。
    • 我刚刚浏览了所有数据,看起来很棒。这很有效并且很容易理解。谢谢! “联盟”仍然给了我想要的数据。
    • 在这种情况下,UNION 和 UNION ALL 得到了相同的结果。
    • 嗯,我卡住了,因为我现在尝试向查询中添加一个文本字段文本数据类型无法选择为 DISTINCT,因为它不可比较。
    【解决方案2】:

    使用不同的别名再次加入jjops,然后从该别名加入hpodt

    SELECT 
        h.jhhold, h.jhjob, h.jhrev, 
        o.jadesc, o.jaoqty, o.jacqty, o.japo, o.javend,
        o2.jadesc, o2.jaoqty, o2.jacqty, o2.japo, o2.javend, 
        p.hdprcd, p.hdrecd, p.hdseq
    FROM Jhead AS h  
    LEFT JOIN
        jjops AS o ON h.jhjob = o.jajob  
    LEFT JOIN
        jjops AS o2 ON h.jhjob = o2.jajob   
    LEFT JOIN
        hpodt AS p ON h.jhjob = p.hdjob
        AND p.hdpo = o2.japo
        AND p.hdseq = o2.jaseq
        AND p.hdjob = h.jhjob
    WHERE 
        h.jhpcmp = 0 
        AND o.jatype = 2 
        AND o.jacqty < o.jaoqty 
        AND o.japcmp = 0 
        AND o.japo = 0;
    

    还要注意,我已经将一些条件移到了ON 子句中。如果需要,您可以随时将它们移回 where 子句:

    ...
    LEFT JOIN
        hpodt AS p ON h.jhjob = p.hdjob
    WHERE 
        h.jhpcmp = 0 
        AND o.jatype = 2 
        AND o.jacqty < o.jaoqty 
        AND o.japcmp = 0 
        AND o.japo = 0
        AND p.hdpo = o2.japo
        AND p.hdseq = o2.jaseq
        AND p.hdjob = h.jhjob;
    

    但是它可能会产生不同的结果 - 最后一个版本将不允许 LEFT JOINo2 返回没有来自 p 的行的行。

    【讨论】:

    • 您的第一个结果给了我很多重复,它为每个 o2.jaseq 显示一行,我认为 o.jatype = 2 没有按照我的需要应用。 Paul Taylors 的回应似乎让我得到了我需要的东西。不过感谢您的帮助。
    【解决方案3】:

    您也可以尝试调整原始语句中的 Where 子句。

    如果您没有多个选择,最好避免对同一个表进行多次选择。

    SELECT h.jhhold, h.jhjob, h.jhrev, o.jadesc, o.jaoqty, o.jacqty, o.japo, o.javend, p.hdprcd, p.hdrecd, p.hdseq 
    FROM Jhead AS h 
    LEFT JOIN jjops AS o ON h.jhjob = o.jajob   
    LEFT JOIN hpodt AS p ON h.jhjob = p.hdjob   
    WHERE h.jhpcmp = 0 
        AND o.jatype = 2 
        AND o.jacqty < o.jaoqty
        AND o.japcmp = 0
        AND (o.japo = 0 
            OR (p.hdjob = h.jhjob AND p.hdpo = o.japo AND p.hdseq = o.jaseq 
                      AND o.japo <> 0))
    

    【讨论】:

    • 这似乎仍然给了我最初声明给我的同样问题。对 hpodt 表的所有选择都会持续拉取 p.hdprcd、p.hdrecd、p.hdseq 的非空结果。由于某种原因,它正在加入不正确的数据。
    • 我认为将 hpodt 上的左连接更改为左连接一个选择语句,其中包括 o.japo 0 将摆脱这些记录的条件 类似left join (select [fields] from jhead as h left join jjops as o on ... left join hpodt as p on .. Where o.japo &lt;&gt; 0) AS MYData
    • 好吧,我编辑了上面应该对你有用的 SQL。您需要将 o.jao &lt;&gt; 0 添加到与您的第二次选择有关的 OR 语句中,这将删除这应该删除您获得的重复记录。
    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 2013-05-31
    • 1970-01-01
    • 2017-07-14
    • 2015-08-30
    • 2012-07-03
    • 2011-07-14
    • 1970-01-01
    相关资源
    最近更新 更多