如何创建一个对 2 个表的条件求和的复杂查询?

How can I create a complex query that sum conditions with 2 tables?

提问人:Carlos Morales 提问时间:12/17/2013 最后编辑:Carlos Morales 更新时间:12/18/2013 访问量:297

问:

我正在尝试在保单有效期内按月net_insurance获得总金额。

这是我的表政策:

ID       date_ini      date_expired  num_policy
1,     '2013-01-01',   '2014-03-08',    1234       
2,     '2012-02-11',   '2013-02-01',    5678  
3,     '2013-03-01',   '2013-08-03',    9123 
4,     '2013-04-01',   '2013-08-01',    4567 
5,     '2013-05-01',   '2013-09-01',    8912 

这是我的餐桌保险

ID      initial_date     final_date  policy_id  net_insurance
1,     '2013-01-16',   '2014-01-01',      1,     1000       
2,     '2013-01-14',   '2014-03-06',      1,     1400
3,     '2012-03-17',   '2013-04-24',      2,     2000  
4,     '2012-02-12',   '2013-02-01',      2,     2500 
5,     '2013-03-09',   '2013-08-20',      3,     3000 
6,     '2013-03-11',   '2013-08-02',      3,     4000 

它将根据此条件(在策略的生命周期内)求和。

WHERE insurances.initial_date >= policies.date_ini
  AND   insurances.final_date <= policies.date_expired                     

根据条件,我应该有这个:

   ID   NUM_POLICY  SUM_INSURANCE
    1   1234              2400
    2   5678              2500
    3   9123              4000
    4   4567               0
    5   8912               0 

这将执行:

 |jan|   |feb|  |mar|  |apr| |may|  |jun|  |jul| |ago| |sep| |oct| |nov| |dec|
  2400    2400  2400    2400  2400    2400  2400  2400  2400   2400 2400   2400
  2500    2500  _______________________________________________________________
  ______________4000    4000  4000   4000  4000  4000  ________________________
  _______________________0    0       0      0    0    ________________________
  ____________________________0       0      0    0     0______________________

以下是每个月总和的最终结果:

 |jan|   |feb|  |mar| |apr|  |may  |jun| |jul| |ago| |sep| |oct| |nov| |dec|
  4900   4900   6400   6400  6400  6400  6400  6400  2400   2400  2400 2400

但是我的查询不起作用,我有另一个值:

 JAN   FEB    MAR     APR     MAY     JUN   JUL   AUG      SEP     OCT     NOV  DEC
 8900  8900  8900   8900    8900    8900    8900    8900    8900    8900    8900    8900

这是我尝试 http://sqlfiddle.com/#!2/e75ea/1

请有人可以帮我解决这个问题吗?

我将不胜感激。

MySQL 数据库

评论

0赞 12/17/2013
您想获取在保单有效期内完全有效的所有记录的总数吗?听起来很有道理。你有桌子吗?您的手动旋转让我的眼睛交叉。net_insuranceinsuranceDates
0赞 12/17/2013
前两个链接工作正常,谢谢。是否有存储日期相关字段的表?这里有几篇文章:techrepublic.com/blog/the-enterprise-cloud/... sqlserverplanet.com/dba/create-date-table这样的表格应该可以使您免于起草繁琐的日期逻辑。
0赞 12/17/2013
示例数据中只有一条记录,其中保险事件完全发生在保单内(保险事件 #1 在保单期间 #1 内)。此记录被策略必须在 2013 年开始和结束的筛选器(在 Fiddle 中)排除。您确定这些过滤器吗?也许过滤事件的开始日期而不是开始和结束日期是有意义的?
1赞 abasterfield 12/18/2013
@JonofAllTrades @Carlitos Morales,我同意,如果您加入条件,则只有一行满足条件,因此问题与 sqlfiddle 不匹配WHERE insurances.initial_date >= policies.date_ini AND insurances.final_date <= policies.date_expiredinsurances.policy_id = policies.id
0赞 12/18/2013
那么你想如何加入呢?按 ID 还是按日期?policiesinsurances

答:

2赞 user565869 12/18/2013 #1

把你的帖子、编辑、评论和SQL小提琴拼凑在一起,并做出一些猜测,听起来你需要这样的东西:

SELECT
    LEFT(DATE_FORMAT(I.initial_date, '%M'), 3) AS Month,
    SUM(I.net_insurance) AS Insurance
FROM
    insurances AS I
    INNER JOIN policies AS P ON I.policy_id = P.id
WHERE
        YEAR(P.date_ini) = 2013
    AND YEAR(P.date_expired) = 2013
GROUP BY
    LEFT(DATE_FORMAT(I.initial_date, '%M'), 3)

至于转透结果数据,不幸的是,这在MySQL中相当麻烦。SO(MySQL数据透视表)的其他地方对此进行了介绍。

评论

0赞 Carlos Morales 12/18/2013
请问你能再读一遍我所有的帖子吗?我添加了详细信息固定数据,还进行了查询,但没有正确进行总和
0赞 Carlos Morales 12/18/2013
这是我想要的 sqlfiddle.com/#!2/e75ea/1 但没有做正确的总和
0赞 12/18/2013
@CarlitosMorales:我已经读了好几遍你的帖子,但一点也不具体。“没有正确地求和”是非常模糊的。我建议你从头开始,清楚地解释你想要实现的目标,包括你的草稿查询,以及你的草稿如何不符合你的预期输出的解释。如果不出意外,您需要明确您是在询问如何聚合数据还是如何透视数据。
3赞 gieffe 12/18/2013 #2

您可以尝试以下查询:

SET @year := 2013;

SELECT
SUM(if (CONCAT(@year, '-01') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Jan,
SUM(if (CONCAT(@year, '-02') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Feb,
SUM(if (CONCAT(@year, '-03') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Mar,
SUM(if (CONCAT(@year, '-04') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Apr,
SUM(if (CONCAT(@year, '-05') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) May,
SUM(if (CONCAT(@year, '-06') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Jun,
SUM(if (CONCAT(@year, '-07') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Jul,
SUM(if (CONCAT(@year, '-08') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Aug,
SUM(if (CONCAT(@year, '-09') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Sep,
SUM(if (CONCAT(@year, '-10') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Oct,
SUM(if (CONCAT(@year, '-11') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) Nov,
SUM(if (CONCAT(@year, '-12') BETWEEN date_format(date_ini, '%Y-%m') AND date_format(date_expired, '%Y-%m'),i.net_insurance, 0)) `Dec`

FROM insurances  i
INNER JOIN policies p ON p.id = i.policy_id 
WHERE (i.initial_date >= p.date_ini
   AND i.final_date   <= p.date_expired) 
  ;

评论

0赞 Carlos Morales 12/19/2013
它奏效了,但你能帮我做最后一件事吗?
0赞 Carlos Morales 12/19/2013
请检查此查询 sqlfiddle.com/#!2/a2638/6。我正在尝试从 2 个查询中获取总和,第一个查询的总和为 type_money= 1,第二个查询的总和为 type_money= 2。我试图得到一个最终的金额
0赞 gieffe 12/19/2013
请看看 sqlfiddle.com/#!2/a2638/19/0,告诉我这是否能解决您的问题。