【问题标题】:Join two sql queries加入两个sql查询
【发布时间】:2010-10-08 13:51:33
【问题描述】:

我有两个 SQL 查询,第一个是:

select Activity, SUM(Amount) as "Total Amount 2009"
from Activities, Incomes
where Activities.UnitName = ? AND
      Incomes.ActivityId = Activities.ActivityID
GROUP BY Activity
ORDER BY Activity;

第二个是:

select Activity, SUM(Amount) as "Total Amount 2008"
from Activities, Incomes2008
where Activities.UnitName = ? AND
      Incomes2008.ActivityId = Activities.ActivityID
GROUP BY Activity
ORDER BY Activity;

(不要介意'?',它们代表 birt 中的一个参数)。 我想要实现的是: 我想要一个返回与第一个查询相同的 SQL 查询,但有一个额外的(第三个)列,看起来完全像“Total Amount 2008”(来自第二个查询)。

【问题讨论】:

  • 加入是一个模糊的术语。你的意思是“外连接”还是“内连接”?两个查询之间不匹配的活动会怎样?

标签: sql database join


【解决方案1】:

您也可以使用 CTE,如下所示。

With cte as
(select Activity, SUM(Amount) as "Total Amount 2009"
   from Activities, Incomes
  where Activities.UnitName = ? AND
        Incomes.ActivityId = Activities.ActivityID
  GROUP BY Activity
),
cte1 as 
(select Activity, SUM(Amount) as "Total Amount 2008"
   from Activities, Incomes2008
  where Activities.UnitName = ? AND
        Incomes2008.ActivityId = Activities.ActivityID
  GROUP BY Activity
)
Select cte.Activity, cte.[Total Amount 2009] ,cte1.[Total Amount 2008]      
  from cte join cte1 ON cte.ActivityId = cte1.ActivityID
 WHERE a.UnitName = ?
 ORDER BY cte.Activity 

【讨论】:

    【解决方案2】:

    这对我有用:

    select visits, activations, simulations, simulations/activations
       as sims_per_visit, activations/visits*100
       as adoption_rate, simulations/activations*100
       as completion_rate, duration/60
       as minutes, m1 as month, Wk1 as week, Yr1 as year 
    
    from
    (
        (select count(*) as visits, year(stamp) as Yr1, week(stamp) as Wk1, month(stamp)
        as m1 from sessions group by week(stamp), year(stamp)) as t3
    
        join
    
        (select count(*) as activations, year(stamp) as Yr2, week(stamp) as Wk2,
        month(stamp) as m2 from sessions where activated='1' group by week(stamp),
        year(stamp)) as t4
    
        join
    
        (select count(*) as simulations, year(stamp) as Yr3 , week(stamp) as Wk3,
        month(stamp) as m3 from sessions where simulations>'0' group by week(stamp),
        year(stamp)) as t5
    
        join
    
        (select avg(duration) as duration, year(stamp) as Yr4 , week(stamp) as Wk4,
        month(stamp) as m4 from sessions where activated='1' group by week(stamp),
        year(stamp)) as t6
    )
    where Yr1=Yr2 and Wk1=Wk2 and Wk1=Wk3 and Yr1=Yr3 and Yr1=Yr4 and Wk1=Wk4
    

    我使用了连接,而不是联合(我需要为每个查询使用不同的列,连接将它们全部放在同一列中)并且我删除了引号(与 Liam 所做的相比),因为它们给了我错误。

    谢谢!没有这个页面,我不可能做到这一点! PS:对不起,我不知道你是如何用颜色格式化你的陈述的。等等

    【讨论】:

      【解决方案3】:

      我只会使用Union

      在您的第二个查询中添加额外的列名并在其他查询中的所有相应位置添加''

      例子

      //reverse order to get the column names
      select top 10 personId, '' from Telephone//No Column name assigned 
      Union 
      select top 10 personId, loanId from loan
      

      【讨论】:

        【解决方案4】:

        试试这个:

        select Activity, SUM(Incomes.Amount) as "Total Amount 2009", SUM(Incomes2008.Amount) 
        as "Total Amount 2008" from
        Activities, Incomes, Incomes2008
        where Activities.UnitName = ?  AND
        Incomes.ActivityId = Activities.ActivityID  AND
        Incomes2008.ActivityId = Activities.ActivityID GROUP BY
        Activity ORDER BY Activity;
        

        基本上,您必须在第一个查询的输出中加入 Income2008 表。

        【讨论】:

        • 因为你使用了内连接,所以结果不会包含2008年没有收入或2009年没有收入的行(即收入表中没有一行)
        • 我最初的尝试看起来像这样。虽然没有工作
        【解决方案5】:

        一些 DBMS 支持 FROM (SELECT ...) AS alias_name 语法。

        将您的两个原始查询视为临时表。您可以像这样查询它们:

        SELECT t1.Activity, t1."Total Amount 2009", t2."Total Amount 2008"
        FROM (query1) as t1, (query2) as t2
        WHERE t1.Activity = t2.Activity
        

        【讨论】:

        • 问题是,如果一个活动为零,则不会显示该活动。可以用这个优雅的解决方案来解决这个问题吗?
        • 如果 Activity 是 (null) 而不是 0,那么左外连接将是小菜一碟。但在这种情况下,恐怕相当困难......
        • 也许您可以将此查询与左侧零和右侧零的特殊情况合并。
        • Mysql 支持这个吗?
        • @frazras 是的。
        【解决方案6】:
        SELECT Activity, arat.Amount "Total Amount 2008", abull.Amount AS "Total Amount 2009"
        FROM
          Activities a
        LEFT OUTER JOIN
          (
          SELECT ActivityId, SUM(Amount) AS Amount
          FROM Incomes ibull
          GROUP BY
            ibull.ActivityId
          ) abull
        ON abull.ActivityId = a.ActivityID
        LEFT OUTER JOIN
          (
          SELECT ActivityId, SUM(Amount) AS Amount
          FROM Incomes2008 irat
          GROUP BY
            irat.ActivityId
          ) arat
        ON arat.ActivityId = a.ActivityID
        WHERE a.UnitName = ?
        ORDER BY Activity
        

        【讨论】:

        • 语句可以编译,但计算的总和很大
        • 对不起,第一次没有得到你想要的。查看更新后的帖子。
        【解决方案7】:

        如果您假设两年中所有活动的值都存在,那么只需按如下方式进行内部联接

         select act.activity, t1.amount as "Total 2009", t2.amount as "Total 2008"
        from Activities as act,
            (select activityid,  SUM(Amount) as amount
            from Activities, Incomes
            where Activities.UnitName = ? AND
                  Incomes.ActivityId = Activities.ActivityID
            GROUP BY Activityid) as t1,
            (select activityid, SUM(Amount) as amount
            from Activities, Incomes2008
            where Activities.UnitName = ? AND
                  Incomes2008.ActivityId = Activities.ActivityID
            GROUP BY Activityid) as t2
            WHERE t1.activityid= t2.activityid
            AND act.activityId = t1.activityId
            ORDER BY act.activity
        

        如果你不能假设这一点,那么看看做一个外连接

        【讨论】:

        • 抱歉,可能有多余的分号。
        【解决方案8】:

        也许不是解决这个问题的最优雅的方法

        select  Activity, 
                SUM(Amount) as "Total_Amount",
                2009 AS INCOME_YEAR
        from    Activities, Incomes
        where Activities.UnitName = ? AND
              Incomes.ActivityId = Activities.ActivityID
        GROUP BY Activity
        ORDER BY Activity;
        
        UNION
        
        select  Activity, 
                SUM(Amount) as "Total_Amount",
                2008 AS INCOME_YEAR
        from Activities, Incomes2008
        where Activities.UnitName = ? AND
              Incomes2008.ActivityId = Activities.ActivityID
        GROUP BY Activity
        ORDER BY Activity;
        

        【讨论】:

          猜你喜欢
          • 2016-01-06
          • 2016-06-13
          • 1970-01-01
          • 1970-01-01
          • 2017-09-10
          • 1970-01-01
          • 2013-05-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多