如何使用条件对列进行求和?

时间:2013-11-20 21:37:04

标签: mysql sql

我正在努力做到这一点:

 date_ini >= initial_date AND final_date <= date_expired

如果不在范围内,将显示保险的最后一次net_insurance

show last_insurance when is not in range

这是我的表格:

   POLICIES
ID  POLICY_NUM     DATE_INI    DATE_EXPIRED   TYPE_MONEY
1,       1234,  "2013-01-01", "2014-01-01"  , 1
2,       5678,  "2013-02-01", "2014-02-01"  , 1
3,       9123,  "2013-03-01", "2014-03-01"  , 1
4,       4567,  "2013-04-01", "2014-04-01"  , 1
5,       8912,  "2013-05-01", "2014-05-01"  , 2
6,       3456,  "2013-06-01", "2014-06-01"  , 2
7,       7891,  "2013-07-01", "2014-07-01"  , 2
8,       2345,  "2013-08-01", "2014-08-01"  , 2

   INSURANCES
 ID POLICY_ID   INITIAL_DATE    FINAL_DATE    NET_INSURANCE
 1,       1,     "2013-01-01",  "2014-01-01",    100
 2,       1,     "2013-01-01",  "2014-01-01",    200
 3,       1,     "2013-01-01",  "2014-01-01",    400
 4,       2,     "2011-01-01",  "2012-01-01",    500
 5,       2,     "2013-01-01",  "2014-01-01",    600
 6,       3,     "2013-01-01",  "2014-01-01",    100
 7,       4,     "2013-01-01",  "2014-01-01",    200

我应该

    POLICY_NUM   NET
        1234     700
        5678     600
        9123     100
        4567     200

这是我试过的

 SELECT  p.policy_num AS policy_num,

 CASE WHEN p.date_ini >= i.initial_date
 THEN SUM(i.net_insurance) 
 ELSE (SELECT max(id) FROM insurances GROUP BY policy_id) END as net

 FROM policies p
 INNER JOIN insurances i ON p.id = i.policy_id AND p.date_ini >= i.initial_date
 GROUP BY p.id

这是我的查询http://sqlfiddle.com/#!2/f6077b/16

有人可以帮我这个吗?

当不在显示我的last_insurance而不是sum

的范围内时不工作

3 个答案:

答案 0 :(得分:1)

以这种方式试试

SELECT p.policy_num, SUM(i.net_insurance) net_insurance
  FROM policies p JOIN insurances i 
    ON p.id = i.policy_id
   AND p.date_ini >= i.initial_date
   AND p.date_expired <= i.final_date
 GROUP BY i.policy_id, p.policy_num
UNION ALL
SELECT p.policy_num, i.net_insurance
  FROM
(
  SELECT MAX(i.id) id
    FROM policies p JOIN insurances i 
      ON p.id = i.policy_id
     AND (p.date_ini < i.initial_date
      OR  p.date_expired > i.final_date)
   GROUP BY i.policy_id
) q JOIN insurances i 
    ON q.id = i.id JOIN policies p
    ON i.policy_id = p.id

输出:

| POLICY_NUM | NET_INSURANCE |
|------------|---------------|
|       1234 |           700 |
|       5678 |           600 |
|       9123 |           100 |
|       4567 |           200 |

这是 SQLFiddle 演示

答案 1 :(得分:0)

如果保单在保单期内没有保险,这将确保您只获得最后一次保险。

SELECT policy_num, SUM(IF(p.cnt > 0, p.net_insurance, i.net_insurance)) AS net_insurance
FROM
(
  SELECT
    p.id,
    p.policy_num,
    SUM(IF(p.date_ini >= i.initial_date AND p.date_expired <= i.final_date, 
  i.net_insurance, 0)) AS net_insurance,
    SUM(IF(p.date_ini >= i.initial_date AND p.date_expired <= i.final_date, 
  1, 0)) AS cnt,
    MAX(IF(p.date_ini >= i.initial_date AND p.date_expired <= i.final_date, 
  0, i.id)) AS max_i_id

  FROM policies p
  INNER JOIN insurances i ON p.id = i.policy_id
  GROUP BY p.id
) as p
LEFT JOIN insurances i ON i.id = p.max_i_id
GROUP BY p.id

这是我的SQLFiddle

答案 2 :(得分:-2)

尝试从条件分割分组:)

SELECT 
  policy_num
  , CASE
    WHEN TRUE
      AND p.date_ini <= src.initial_date
      AND p.date_expired >= src.final_date
    THEN src.sum_insurances
    ELSE i.net_insurance
  END AS something
FROM (
  SELECT 
    max(id) AS latest_id
    , sum(net_insurance) AS sum_insurances
    , initial_date
    , final_date
    , policy_id
  FROM insurances
  GROUP BY policy_id
) src
JOIN policies p ON p.id = src.policy_id
JOIN insurances i ON i.id = src.latest_id
ORDER BY p.id