存储过程内的月计算

时间:2013-11-17 09:28:02

标签: mysql sql date stored-procedures

我需要获取一个不在数据库中的月份列表。

示例:

成员

ID | Member's code | Member since
1  |  555-12       |  2012-11-22

成员资格

ID |   Code  | Paid
1  |  555-12 | 2013-1-1
2  |  555-12 | 2013-3-12
3  |  555-12 | 2013-5-1

让我们说今天是:2013-11-17

我需要得到这样的输出:

Member's code  |  Debt ( Months )
555-12         |    11-2012
555-12         |    12-2012
555-12         |     2-2013
555-12         |     4-2013

这可能与SQL有关吗?我是否需要stored procedure我将通过Member's code

3 个答案:

答案 0 :(得分:1)

select code,
left(since,7) as debt 
from user where code='555-12'

union all

select code,
left(date_add(paid, interval -1 MONTH),7) as debt 
from paid where code='555-12'

<强>小提琴

http://sqlfiddle.com/#!2/3d988/1

答案 1 :(得分:1)

我的想法是使用一个数字表,其中只包含0到100或更多的数字:

CREATE TABLE numbers (
  n INT
);

INSERT INTO numbers (n)
VALUES
(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)...;

然后你可以使用这样的查询:

SELECT
  m.ID,
  m.Code,
  DATE_FORMAT(m.Member_since + INTERVAL num.n MONTH, '%m-%Y') As Debt_Month_Year
FROM
  members m INNER JOIN numbers num
  ON TIMESTAMPDIFF(MONTH, m.Member_since, LAST_DAY(CURDATE()))>=num.n
  LEFT JOIN membership ms
  ON
    m.Code = ms.Code
    AND
      LAST_DAY(ms.Paid)=LAST_DAY(m.Member_since + INTERVAL num.n MONTH)
WHERE
  ms.id IS NULL
  -- and if you wish, add the following line:
  AND m.Code = '555-12'

请参阅小提琴here

答案 2 :(得分:0)

如果您可以保证每个用户的条目之间只有一个月的差距,那么我认为Timus的解决方案应该有效。

如果没有,我认为你需要有一些日期表来确定你在数据库中没有的值。

这是一个SQL小提琴演示我正在谈论的内容。我故意从付费表中删除其中一行,以测试跳过一个多月。基本上它从成员表中获取月份(我猜是第一个条目),并且我将其与第二个查询联合起来,以获得不在付费表中的月份。

SQL Fiddle

select
left (mbr_since,7) as MNTH
from
user
union

select
mnth
from
months
left outer join paid
on months.mnth = left(paid,7)
where
paid.code is null

月份表每个月只有一行(2013-01,2013-02等)。第二个查询加入到那个,然后筛选出付费表中匹配的行。希望我的解释是有道理的......