我正在尝试为客户端创建一个管理面板,但是我的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,Jane和Joe的列表。

我面临的问题是,如果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,因为John支付了上一年的费用,而查询认为他也为此支付了费用。

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

最佳答案

您需要指定对查询感兴趣的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

关于mysql - 获取在xxxx年内未付款的成员(member)列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53199271/

10-16 15:26