【问题标题】:Joining 2 unequal sql queries加入 2 个不相等的 sql 查询
【发布时间】:2017-11-22 05:51:27
【问题描述】:

我有 2 个选择查询,我想加入一个没有重复的查询。此外,我想使用在所有表中找到的 shiftindex 主键加入他们。我该怎么做?

第一个选择语句是:

SELECT     dbo.hist_exproot.year, 
           dbo.hist_exproot.[month#], 
           dbo.hist_exproot.month, 
           dbo.hist_exproot.day, 
           dbo.hist_exproot.[shift#], 
           dbo.hist_exproot.shift, 
           dbo.hist_loads.excav, 
           SUM(dbo.hist_loads.loadtons) AS 'TONS', 
           SUM(dbo.hist_loads.ex_tmcat00)/3600 AS 'TTOTAL', 
           SUM(dbo.hist_loads.ex_tmcat01+dbo.hist_loads.ex_tmcat02)/3600 AS 'T_EFECT'
FROM       dbo.hist_exproot 
INNER JOIN dbo.hist_loads 
           ON dbo.hist_exproot.shiftindex = dbo.hist_loads.shiftindex
WHERE     (dbo.hist_exproot.year >= 16)
GROUP BY  dbo.hist_exproot.year, 
          dbo.hist_exproot.[month#], 
          dbo.hist_exproot.month, 
          dbo.hist_exproot.day, 
          dbo.hist_exproot.[shift#], 
          dbo.hist_exproot.shift, 
          dbo.hist_loads.excav

第二个是:

SELECT     dbo.hist_exproot.year,
           dbo.hist_exproot.[month#], 
           dbo.hist_exproot.shiftdate, 
           dbo.hist_exproot.shift, 
           dbo.hist_statusevents.eqmt, 
           dbo.hist_exproot.crew, 
           dbo.hist_reasontable.category, 
           dbo.hist_statusevents.reason, 
           dbo.hist_reasontable.name, 
           dbo.hist_operlist.operid, 
           dbo.hist_statusevents.starttime, 
           dbo.hist_statusevents.endtime, 
           dbo.hist_statusevents.duration/3600 as 'Time', 
           dbo.hist_statusevents.comment
FROM       dbo.hist_reasontable 
INNER JOIN dbo.hist_statusevents 
           ON dbo.hist_reasontable.shiftindex = dbo.hist_statusevents.shiftindex 
           AND dbo.hist_reasontable.reason = dbo.hist_statusevents.reason 
INNER JOIN dbo.hist_operlist 
           ON dbo.hist_statusevents.operid = dbo.hist_operlist.operid 
           AND dbo.hist_statusevents.shiftindex = dbo.hist_operlist.shiftindex 
           AND dbo.hist_reasontable.shiftindex = dbo.hist_operlist.shiftindex 
INNER JOIN dbo.hist_exproot 
           ON dbo.hist_statusevents.shiftindex = dbo.hist_exproot.shiftindex
WHERE      
           (dbo.hist_exproot.year >= 16) 
            AND (dbo.hist_statusevents.unit = 2) 
            AND(dbo.hist_statusevents.eqmt <> 'L98') 
            AND (dbo.hist_statusevents.eqmt <> 'L96')
            AND  (dbo.hist_statusevents.eqmt <> 'L09')
            AND (dbo.hist_statusevents.eqmt <> 'S47')
ORDER BY dbo.hist_exproot.shiftdate, 
         dbo.hist_statusevents.eqmt

如果您有任何问题,请告诉我。

谢谢

【问题讨论】:

  • 除非您实际上以某种方式使用 MySQL,否则 mysql 标签可能不适用,应该删除。
  • 您迫切需要使用别名。这个查询读起来简直是噩梦。
  • 假设这确实是 T-SQL,CTE 是你的朋友,无论查询多么不可读。 WITH T1 AS (SELECT ...), T2 AS (SELECT ...) SELECT * FROM T1 JOIN T2 ON ...。不过,子查询中的ORDER BY 子句需要删除。

标签: mysql sql-server tsql


【解决方案1】:

我假设您使用的是 SQL Server。

正如其他人指出的那样,一种方法是使用像 SELECT DISTINCT column_list FROM CTE1 INNER JOIN CTE2 ON join_condition 这样的 CTE,其中 CTE1 和 CTE2 是没有 ORDER BY 子句的原始查询。基于您的示例的连接列将是 dbo.hist_exproot.shiftindex

另一种方法是按如下方式连接所有表...

SELECT 
    he.year
    , he.[month#]
    , he.month
    , he.day
    , he.[shift#]
    , he.shift
    , hl.excav
    , SUM(hl.loadtons) AS 'TONS'
    , SUM(hl.ex_tmcat00)/3600 AS 'TTOTAL'
    , SUM(hl.ex_tmcat01+hl.ex_tmcat02)/3600 AS 'T_EFECT'
    , he.shiftdate
    , se.eqmt
    , he.crew
    , rt.category
    , se.reason
    , rt.name
    , ol.operid
    , se.starttime
    , se.endtime
    , se.duration/3600 as 'Time'
    , se.comment
FROM 
    dbo.hist_exproot he
    INNER JOIN dbo.hist_loads hl ON he.shiftindex = hl.shiftindex
    INNER JOIN dbo.hist_statusevents se ON se.shiftindex = he.shiftindex
    INNER JOIN dbo.hist_reasontable rt ON rt.shiftindex = se.shiftindex 
                                          AND rt.reason = se.reason
    INNER JOIN dbo.hist_operlist ol ON se.operid = ol.operid 
                                       AND se.shiftindex = ol.shiftindex 
                                       AND rt.shiftindex = ol.shiftindex 
WHERE 
    he.year >= 16
    AND se.unit = 2
    AND se.eqmt <> 'L98'
    AND se.eqmt <> 'L96'
    AND se.eqmt <> 'L09'
    AND se.eqmt <> 'S47'
GROUP BY 
    he.year
    , he.[month#]
    , he.MONTH
    , he.DAY
    , he.[shift#]
    , he.shift
    , hl.excav
ORDER BY 
    he.shiftdate
    , se.eqmt

如果您想从结果集中消除任何可能的重复项,请使用DISTINCT 子句。但如果你不需要它,最好避免它。

连接所有表的第二种解决方案会导致更复杂的查询,并且可能没有最佳查询计划。我会尝试这两种方法并使用更有效的一种。

感谢 Sean Lange 重新格式化原始查询。

【讨论】:

    【解决方案2】:

    这不是一个答案,但对于评论来说太长了。如果您使用别名,这就是您的查询的样子。我还清理了一些其他格式,以便您可以看到它应该是什么样子。

    SELECT he.year
        , he.[month#]
        , he.month
        , he.day
        , he.[shift#]
        , he.shift
        , hl.excav
        , SUM(hl.loadtons) AS 'TONS'
        , SUM(hl.ex_tmcat00)/3600 AS 'TTOTAL'
        , SUM(hl.ex_tmcat01+hl.ex_tmcat02)/3600 AS 'T_EFECT'
    FROM dbo.hist_exproot he
    INNER JOIN dbo.hist_loads hl ON he.shiftindex = hl.shiftindex
    WHERE he.year >= 16
    GROUP BY he.year
        , he.[month#]
        , he.MONTH
        , he.DAY
        , he.[shift#]
        , he.shift
        , hl.excav
    
    
    
    SELECT er.year
        , er.[month#]
        , er.shiftdate
        , er.shift
        , se.eqmt
        , er.crew
        , rt.category
        , se.reason
        , rt.name
        , ol.operid
        , se.starttime
        , se.endtime
        , se.duration/3600 as 'Time'
        , se.comment
    FROM dbo.hist_reasontable rt
    INNER JOIN dbo.hist_statusevents se ON rt.shiftindex = se.shiftindex 
                AND rt.reason = se.reason 
    INNER JOIN dbo.hist_operlist ol ON se.operid = ol.operid 
                AND se.shiftindex = ol.shiftindex 
                AND rt.shiftindex = ol.shiftindex 
    INNER JOIN dbo.hist_exproot er ON se.shiftindex = er.shiftindex
    WHERE er.year >= 16
        AND se.unit = 2
        AND se.eqmt <> 'L98'
        AND se.eqmt <> 'L96'
        AND se.eqmt <> 'L09'
        AND se.eqmt <> 'S47'
    ORDER BY er.shiftdate
        , se.eqmt
    

    【讨论】:

    • 大声笑我按原样编辑了问题。看,我对代码语法和样式有点眼花缭乱。没关系理解它。
    【解决方案3】:

    满足您的要求的最简单方法是:

    SELECT DISTINCT *
    FROM (Query 1) JOIN
    (Query 2) ON...
    

    这两个子查询的连接将由您在 on 之后放置的内容处理,并且 distinct 将消除所有重复项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-02
      • 2023-01-13
      • 1970-01-01
      • 2018-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多