MySQL水平加入两个查询

时间:2012-04-27 21:19:52

标签: mysql

我有一个查询可以正确地为公司A提取一系列目标和工作总时间。我想为公司B运行完全相同的查询并在共同日期加入它们,这恰好按照周。我目前的查询:

SELECT * FROM (
  SELECT org, date,
         ( SELECT SUM( target ) FROM target WHERE org = "companyA" ) AS companyA_target,
         SUM( hours ) AS companyA_actual
  FROM time_management_system
  WHERE org = "companyA"
  GROUP BY WEEK( date )
  ORDER BY DATE
) q1

LEFT JOIN (
  SELECT org, date,
         ( SELECT SUM( target ) FROM target WHERE org = "companyB" ) AS companyB_target,
         SUM( hours ) AS companyB_actual
  FROM time_management_system
  WHERE org = "companyB"
  GROUP BY WEEK( date )
  ORDER BY DATE
) q2 

ON q1.date = q2.date

结果显示了公司A的所有日期/信息,但是公司B只显示零星的数据。另外,两个查询将显示完全相同的日期集,只是在“目标”和“实际”列中显示不同的信息。

companyA    2012-01-28  105.00  39.00   NULL      NULL          NULL   NULL 
companyA    2012-02-05  105.00  15.00   NULL      NULL          NULL   NULL
companyA    2012-02-13  105.00  60.50   companyB  2012-02-13    97.50  117.50

知道为什么我没有获得公司B的所有信息吗?

作为旁注,是否有人能够指出将每行的周值转换为列的方向?将companyA和companyB作为唯一的两行?

我感谢所有的帮助!感谢。

2 个答案:

答案 0 :(得分:1)

您的两个子查询都是错误的。

要么你想要这个:

SELECT 
org,
WEEK(date),
( SELECT SUM( target ) FROM target WHERE org = "companyB" ) AS companyB_target,
SUM( hours ) AS companyB_actual
FROM time_management_system
WHERE org = "companyB"
GROUP BY WEEK( date )

或者你想要这个:

SELECT 
org,
date,
( SELECT SUM( target ) FROM target WHERE org = "companyB" ) AS companyB_target,
SUM( hours ) AS companyB_actual
FROM time_management_system
WHERE org = "companyB"
GROUP BY date

你现在的方式是没有正确形成SQL。在几乎任何其他数据库中,您的查询将立即失败并出现错误。 MySQL更加宽松并运行查询,但会产生不确定的结果。

答案 1 :(得分:1)

目标表中没有显示日期,总和将在所有周内保持不变。所以,我只对公司A和B的那些“组织”值进行了预查询。这将确保每个“组织”只有1条记录,因此您不会得到笛卡尔结果。

然后,我正在查询两家公司的time_management_system ONCE。在现场计算中,我正在应用IF()来测试公司价值并在正确时应用。 WEEK活动在最终结果中都是相同的,所以我不必单独进行并加入。这也可以防止日期列出现两次。我也不需要显式添加组织列名称,因为最终的列名称反映了这一点。

SELECT
      WEEK( tms.date ) as GrpWeek,
      IF( tms.org = "companyA", TargetSum.CompTarget, 00000.00 )) as CompanyATarget,
      SUM( IF( tms.org = "companyA", tms.hours, 0000.00 )) as CompanyAHours,
      IF( tms.org = "companyB", TargetSum.CompTarget, 00000.00 )) as CompanyBTarget,
      SUM( IF( tms.org = "companyB", tms.hours, 000.00 )) as CompanyBHours
   from
      Time_Management_System tms
         JOIN ( select 
                      t.org,
                      SUM( t.target ) as CompTarget
                   from 
                      Target T
                   where
                      t.org in ( "companyA", "companyB" ) 
                   group by
                      t.org ) as TargetSums
            ON tms.org = TargetSums.org
   where 
      tms.org in ( "companyA", "companyB" )
   group by
      WEEK( tms.date )
   order by
      WEEK( tms.date )