获取在xxxx年内未付款的会员列表

时间:2018-11-07 23:08:51

标签: mysql sql

我试图为客户端创建一个管理面板,但是我的SQL查询遇到一些麻烦。

我想做的是,显示一个页面,其中包含所有为xxxx年付款的会员(例如:2018年)的数据表。并为他添加一个小的选择按钮,以便在xxxx年内支付的会员和未支付的会员之间进行过滤。

成员的表架构很简单:

id
first_name
last_name
email
number
active

关于付款逻辑,我将年费和付款分成了两个单独的表。

付款:

member_id
year_id
notes
paid
paid_at
created_at
updated_at

年费:

id
year
amount
created_at
updated_at

获取付款用户非常简单。我加入了三个表并选择了与他指定的年份相匹配的行:

SELECT `payments`.`id` AS `paymentID`,
       `payments`.`notes`, `payments`.`paid_at`, 
       `members`.`first_name`, `members`.`last_name`, 
       `members`.`id` AS `memberID`, `payments`.`paid`, 
       `yearly_fees`.`year`, 
       FORMAT(yearly_fees.amount, 0) AS yearlyAmount 
FROM `members` 
    INNER JOIN `payments` 
        ON `payments`.`member_id` = `members`.`id` 
    INNER JOIN `yearly_fees`
        ON `yearly_fees`.`id` = `payments`.`year_id` 
WHERE `payments`.`year_id` = ?

但是现在我遇到了没有付款的用户列表的麻烦。我会尽力给出一个确切发生的事的示例,但是如果我无法尽可能清楚地说明这一点,我会提前道歉,因为这是我第一次这样做。

假设我们的表中有三个成员。 John DoeJane DoeJoe Bloggs。简(Jane)和乔(Joe)已经为他们的2018年会员资格付款,其数据可以在付款页面中看到。并且,如果管理员点击了unpaid过滤器,他会发现John Doe是唯一剩下的一个没有付款的人。但是明天是2019年,现在管理员已为2019年开立了新的年费。现在,如果他想过滤为未付款,他应该获得约翰,简和乔的清单。

我面临的问题是,如果John为2018年而不是2019年支付了费用,则SQL查询不会与其他未付费成员一起获取他的名字,因为它认为他确实已经支付了。而且无论我做什么,我似乎都找不到合适的逻辑来工作。我不知道是因为我写错了查询还是因为我做错了架构,还是因为我应该制作另一个表来处理这种逻辑。

我尝试使用的SQL查询如下:

SELECT `members`.`id` AS `memberID`, 
       `members`.`first_name`, 
       `members`.`last_name` 
FROM `members` 
    LEFT JOIN `payments` 
        ON `payments`.`member_id` = `members`.`id`
    LEFT JOIN `yearly_fees` 
        ON `yearly_fees`.`id` = `payments`.`year_id` 
WHERE `payments`.`member_id` IS NULL

2019年的结果将如下所示:

Jane Doe, Joe Bloggs

它没有得到John Doe,因为约翰支付了上一年的费用,而查询认为他也为此支付了费用。

希望我能相应地解释我的问题,如果您需要更多说明,请告诉我。

1 个答案:

答案 0 :(得分:0)

您需要在查询中指定您感兴趣的year_id。与ON联接时,必须进入payments子句。

SELECT `members`.`id` AS `memberID`, 
       `members`.`first_name`, 
       `members`.`last_name` 
FROM `members` 
LEFT JOIN `payments` 
    ON `payments`.`member_id` = `members`.`id` AND payments.year_id = ?
WHERE payments.id IS NULL

DEMO