我需要获取一个不在数据库中的月份列表。
示例: 的
表成员
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
?
答案 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'
<强>小提琴强>
答案 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等)。第二个查询加入到那个,然后筛选出付费表中匹配的行。希望我的解释是有道理的......