我试图为客户端创建一个管理面板,但是我的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 Doe
,Jane Doe
,Joe 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
,因为约翰支付了上一年的费用,而查询认为他也为此支付了费用。
希望我能相应地解释我的问题,如果您需要更多说明,请告诉我。
答案 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