mysql图表子查询

mysql图表子查询,mysql,group-by,subquery,Mysql,Group By,Subquery,我有两个表,其中包含以下数据 可邀请的 inviteDate | contractAmount | status 2014-01-01 1500 awarded 2015-01-01 2000 awarded 2015-01-02 4000 closed 2015-02-01 6000 awarded 2015-02-02 8000

我有两个表,其中包含以下数据

可邀请的

inviteDate  | contractAmount | status

2014-01-01     1500             awarded
2015-01-01     2000             awarded
2015-01-02     4000             closed
2015-02-01     6000             awarded
2015-02-02     8000             awarded
2015-03-01     8500             awarded
可引用

quoteDate  | quoteAmount | status

2014-03-01     1500         awarded
2015-01-02     2000         awarded
2015-01-03     4000         sent
2015-01-04     6000         awarded
2015-02-03     8000         awarded
2015-02-10     8500         sent
2015-02-11     9000         awarded
2015-03-01     9500         awarded
我想进行一个查询,该查询提供以下数据结构

month   | quotedTotal | quotedCount | awardedTotal | awardedCount

January      8000           2             2000            1
February    17000           2            14000            2
March        9500           1             8500            1
目前我已经写了这段代码…但它不起作用

  SELECT
    MONTHNAME(t1.due_date) as month,
    (select sum(`amount`) from quoteTable where awarded= 1 ) as estimatedAmount,    
     sum(t1.contactAmount) AS sumContactAmount,
     COUNT(*) as `noOfAwarded`

    FROM inviteTable t1 

    where

    t1.status = "Awarded" and 
    t1.inviteDate between '2014-11-01' and '2015-10-31'

 GROUP BY MONTH(due_date)
    ;
基本上,我希望有一个查询,该查询提供以下信息:

  • 获得奖励的数量-合同金额和授予状态的总和
  • 已授予的数量计数-可邀请的计数。状态=已授予
  • 获得报价的数量-报价数量和授予状态的总和
  • 报价数量计数-报价表计数。状态=已授予
  • 按月份和日期范围进行分组


    我的查询不起作用。我被困住了,非常感谢你的帮助

    这是一种方法,请注意,两个表中都有日期,最好使用join
    left join
    ,这样可以确保在这种情况下,左表中的日期始终返回月份名称

    select
    t1.month,
    t1.awardedTotal,
    t1.awardedCount,
    t2.quotedTotal,
    t2.quotedCount 
    from(
      select
      monthname(t1.inviteDate) as month,
      month(t1.inviteDate) as m,
      sum( 
        case 
         when t1.status = 'awarded' then t1.contractAmount else 0
        end
      ) as awardedTotal,
      sum( 
        case 
         when t1.status = 'awarded' then 1 else 0
        end
      ) as awardedCount
      from inviteTable t1 
      where t1.inviteDate between '2014-11-01' and '2015-10-31'
      group by month 
    )t1 
    left join(
      select
      monthname(t2.quoteDate) as month,
      sum( 
        case 
         when t2.status = 'awarded' then t2.quoteAmount else 0
        end
      ) as quotedTotal,
      sum( 
        case 
         when t2.status = 'awarded' then 1 else 0
        end
      ) as quotedCount
      from quoteTable t2 
      where t2.quoteDate between '2014-11-01' and '2015-10-31'
      group by month
    )t2 on
    t1.month = t2.month
    order by t1.m
    

    更新: 是的,因为您希望两个表中存在日期,所以不能用上述过程完成,因为它总是将一个表视为左表,并从表中获取所有日期。要获取两个表中所有日期的数据,首先需要从两个表中获取日期,然后使用left join获取计算部分

    select
    t1.month,
    coalesce(t2.awardedTotal,0) as awardedTotal,
    coalesce(t2.awardedCount,0) as awardedCount,
    coalesce(t3.quotedTotal,0) as quotedTotal,
    coalesce(t3.quotedCount,0) as quotedCount
    from(
      select month(inviteDate) as m,monthname(inviteDate) as month 
      from inviteTable where inviteDate between '2014-11-01' and '2015-10-31'
      union
      select month(quoteDate) as m,monthname(quoteDate) as month
      from quoteTable where quoteDate between '2014-11-01' and '2015-10-31'
    )t1
    left join(
      select
      monthname(inviteDate) as month,
      sum( 
        case 
         when status = 'awarded' then contractAmount else 0
        end
      ) as awardedTotal,
      sum( 
        case 
         when status = 'awarded' then 1 else 0
        end
      ) as awardedCount
      from inviteTable 
      group by month 
    )t2 on t1.month = t2.month
    left join(
      select
      monthname(quoteDate) as month,
      sum( 
        case 
         when status = 'awarded' then quoteAmount else 0
        end
      ) as quotedTotal,
      sum( 
        case 
         when status = 'awarded' then 1 else 0
        end
      ) as quotedCount
      from quoteTable 
      group by month
    )t3 on t1.month=t3.month
    order by t1.m
    

    这里是一种方法,请注意,两个表中都有日期,最好使用join
    左join
    ,这样可以确保在这种情况下,左表中的日期始终返回月份名称

    select
    t1.month,
    t1.awardedTotal,
    t1.awardedCount,
    t2.quotedTotal,
    t2.quotedCount 
    from(
      select
      monthname(t1.inviteDate) as month,
      month(t1.inviteDate) as m,
      sum( 
        case 
         when t1.status = 'awarded' then t1.contractAmount else 0
        end
      ) as awardedTotal,
      sum( 
        case 
         when t1.status = 'awarded' then 1 else 0
        end
      ) as awardedCount
      from inviteTable t1 
      where t1.inviteDate between '2014-11-01' and '2015-10-31'
      group by month 
    )t1 
    left join(
      select
      monthname(t2.quoteDate) as month,
      sum( 
        case 
         when t2.status = 'awarded' then t2.quoteAmount else 0
        end
      ) as quotedTotal,
      sum( 
        case 
         when t2.status = 'awarded' then 1 else 0
        end
      ) as quotedCount
      from quoteTable t2 
      where t2.quoteDate between '2014-11-01' and '2015-10-31'
      group by month
    )t2 on
    t1.month = t2.month
    order by t1.m
    

    更新: 是的,因为您希望两个表中存在日期,所以不能用上述过程完成,因为它总是将一个表视为左表,并从表中获取所有日期。要获取两个表中所有日期的数据,首先需要从两个表中获取日期,然后使用left join获取计算部分

    select
    t1.month,
    coalesce(t2.awardedTotal,0) as awardedTotal,
    coalesce(t2.awardedCount,0) as awardedCount,
    coalesce(t3.quotedTotal,0) as quotedTotal,
    coalesce(t3.quotedCount,0) as quotedCount
    from(
      select month(inviteDate) as m,monthname(inviteDate) as month 
      from inviteTable where inviteDate between '2014-11-01' and '2015-10-31'
      union
      select month(quoteDate) as m,monthname(quoteDate) as month
      from quoteTable where quoteDate between '2014-11-01' and '2015-10-31'
    )t1
    left join(
      select
      monthname(inviteDate) as month,
      sum( 
        case 
         when status = 'awarded' then contractAmount else 0
        end
      ) as awardedTotal,
      sum( 
        case 
         when status = 'awarded' then 1 else 0
        end
      ) as awardedCount
      from inviteTable 
      group by month 
    )t2 on t1.month = t2.month
    left join(
      select
      monthname(quoteDate) as month,
      sum( 
        case 
         when status = 'awarded' then quoteAmount else 0
        end
      ) as quotedTotal,
      sum( 
        case 
         when status = 'awarded' then 1 else 0
        end
      ) as quotedCount
      from quoteTable 
      group by month
    )t3 on t1.month=t3.month
    order by t1.m
    

    你的模式很不幸;如果您只有一个表和一个额外的列来记录您所拥有的记录类型,那么就更容易了。但是,如果首先通过
    union all
    将两个表收集到一个表中,则可以使用相当简单的查询生成所需的结果:

    select
      monthname(_date) month,
      sum(quoteAwarded * amount) quotedTotal,
      sum(quoteAwarded) quotedCount,
      sum(contractAwarded * amount) awardedTotal,
      sum(contractAwarded) awardedCount
    from (select inviteDate _date, contractAmount amount, status = 'awarded' contractAwarded, 0 quoteAwarded from inviteTable
      union all
      select quoteDate, quoteAmount, 0, status = 'awarded' from quoteTable) x
    where _date between '2014-11-01' and '2015-10-31'
    group by 1
    order by month(_date)
    
    请参见使用示例数据和生成预期输出


    这个查询的核心是一个方便的事实,(在mysql中)“true”是1,“false”是0-允许使用
    sum()
    而不是
    count()
    ,更重要的是,通过在一些简单的数学上使用
    sum()
    避免使用
    case
    ;如果您只有一个表和一个额外的列来记录您所拥有的记录类型,那么就更容易了。但是,如果首先通过
    union all
    将两个表收集到一个表中,则可以使用相当简单的查询生成所需的结果:

    select
      monthname(_date) month,
      sum(quoteAwarded * amount) quotedTotal,
      sum(quoteAwarded) quotedCount,
      sum(contractAwarded * amount) awardedTotal,
      sum(contractAwarded) awardedCount
    from (select inviteDate _date, contractAmount amount, status = 'awarded' contractAwarded, 0 quoteAwarded from inviteTable
      union all
      select quoteDate, quoteAmount, 0, status = 'awarded' from quoteTable) x
    where _date between '2014-11-01' and '2015-10-31'
    group by 1
    order by month(_date)
    
    请参见使用示例数据和生成预期输出


    这个查询的核心是一个方便的事实,(在mysql中)“true”是1,“false”是0-允许使用
    sum()
    而不是
    count()
    ,更重要的是通过使用
    sum()避免使用
    case
    跳过一些简单的数学。

    请提供
    fiddle
    链接来表示您的表和数据,这可以帮助每个人轻松找到解决方案。@user2062455您正在寻找,尽管您还应该提到它是如何工作的。另一个问题是,结果必须与两个表匹配或不匹配。例如,对于
    一月
    是否可能只有一个表有记录。请提供
    fiddle
    链接来表示您的表和数据,这可以帮助每个人轻松找到解决方案。@user2062455,尽管您还应该提到它是如何不起作用的。另一个问题是,结果必须与两个表匹配或不匹配。例如,对于
    一月
    是否可能只有一个表有记录。如果一个表中只有月份的日期,则这不起作用。看看exmaple:我应该说得更清楚一点。我正试图得到一份所有月份的列表,以及相应月份中的awardedTotal、awardedCount、quotedTotal、quotedCount的数据months@user2062455是如果需要表中的所有日期,则需要修改查询,检查更新的答案。如果一个表中只有月份的日期,则此操作无效。看看exmaple:我应该说得更清楚一点。我正试图得到一份所有月份的列表,以及相应月份中的awardedTotal、awardedCount、quotedTotal、quotedCount的数据months@user2062455是如果您需要表中的所有日期,那么您需要修改查询,请检查更新的答案。很遗憾,我无法将所有数据放在一个表中。你的解决方案很有魅力。Abhik的更新同样有效,但你的代码更少。谢谢你们两位的输入不幸的是,我不能把所有的数据都放在一个表中。你的解决方案很有魅力。Abhik的更新同样有效,但你的代码更少。谢谢你们两位的意见