【问题标题】:SQL for a Household Bill splitting db家庭账单拆分数据库的 SQL
【发布时间】:2013-06-12 12:05:30
【问题描述】:

我正在尝试为 PHP 页面构建一个 mySQL 数据库,该页面将允许用户输入账单成本并选择与谁分摊账单。我遇到的问题是我不知道如何计算居民之间的总欠款,考虑到他们已经支付的费用以及他们需要支付给其他人的费用。

我希望它能够处理可变数量的“居民”用户,因此设计了如下表格:

用户表:

 UserID | User    
 -------+---------
 1      | Jon
 2      | Boris
 3      | Natalie

账单表:

 BillID |  BIll  |  Amount  |  Paid By (UserID F.Key)
 -------+--------+----------+--------------
 1      | Gas    | £30.00   |  1 (Jon)
 2      | Water  | £30.00   |  1 (Jon)
 3      | Tax    | £60.00   |  2 (Boris)
 4      | Phone  | £10.00   |  2 (Boris)

因此,此表显示电话费为 10.00 英镑,鲍里斯为此向电话公司支付了费用。

账单-用户负债连接表:

 UserID_fKey | BillID_fKey 
 ------------+--------------
 1 (Jon)     | 1 (Gas)
 2 (Boris)   | 1 (Gas)
 3 (Nat)     | 1 (Gas)
 1 (Jon)     | 2 (Water)
 2 (Boris)   | 2 (Water)
 3 (Nat)     | 2 (Water)
 1 (Jon)     | 3 (Tax)
 2 (Boris)   | 3 (Tax)
 1 (Jon)     | 4 (Phone)
 2 (Boris)   | 4 (Phone)

Bill-Users 表用于描述每个账单的责任人。因此,例如,娜塔莉从不使用手机,因此不需要为鲍里斯支付任何费用。因此,电话费由 Borris 和 Jon 分摊。因此,乔恩欠鲍里斯 5 英镑。

我认为这是最好的方法,但我不知道如何在每个用户登录时为他们生成一张表,以显示他们彼此之间的欠款。为此(例如),我需要将 Jon 支付的所有费用、每个人代表 Jon 支付的费用加起来并计算出余额。显然,这需要扩展,以便系统中可以有 3 个或更多用户。

这是我想要得到的结果:

(例如:以 Jon 身份登录)

 User    | Amount Owed
---------+-------------
 Boris   | -£15.00
 Natalie |  £20.00

非常感谢。

【问题讨论】:

    标签: php mysql sql billing recurring-billing


    【解决方案1】:

    您需要在账单表中添加一个欠款字段才能执行最低操作。

    选择个人用户

    SELECT Users.User, Bills.BIll, Bills.owe, Bills.Amount
    FROM Users
    LEFT JOIN Bills ON Users.UserID = Bills.UserID
    WHERE Users.UserID =1
    

    选择所有用户

    SELECT Users.User, Bills.BIll, Bills.owe, Bills.Amount
    FROM Users
    LEFT JOIN Bills ON Users.UserID = Bills.UserID
    LIMIT 0 , 30
    

    选择所有用户的付费总和

    SELECT Users.User, Bills.BIll, sum(Bills.owe), sum(Bills.Amount), sum(Bills.owe)- sum(Bills.Amount) as arrears
    FROM Users
    LEFT JOIN Bills ON Users.UserID = Bills.UserID
    GROUP BY Users.UserID;
    

    demo

    【讨论】:

    • 我对@9​​87654325@ 表中的数字从何而来感到有些困惑。如果煤气费是 30 英镑,乔恩付了,那么鲍里斯和娜塔莉各欠乔恩 10 英镑……那么owe 表不应该包含 10 英镑吗?
    • @pugu 这只是一个示例,您可以随意编辑。我不知道如何输入或使用数据的全部范围。你说的没必要。我欠了50,我欠了20,欠了30。是一个人付账吗?
    【解决方案2】:

    最后我通过一个函数实现了这一点。它可能无法很好地扩展到 100 名用户,但仍然给了我想要的灵活性。我正在尝试启动一个 SQLFiddle 来演示它,但遇到了问题。

    Set @CurrentUser = '1' (Jon)
    
    Select User, funcAmountOwed(@currentuser,UserID) from Users
    WHERE UserID != @CurrentUser;
    

    返回:

     User    | Amount Owed
    ---------+-------------
     Boris   | -£15.00
     Natalie |  £20.00
    

    函数大致如下:

    funcAmountOwed(@CurrentUser, @CurrentDebtor);
    
    SET @AmountPaidByCurrentUser = (
    
    Select SUM(Amount) from Bills b
    INNER JOIN BillsUsers bu ON b.BillID = bu.BillID_fkey
    WHERE b.PaidBy = @CurrentUser and bu.UserId_fkey = @CurrentDebtor)
    
    SET @AmountPaidByDebtor = (
    
    Select SUM(Amount) from Bills b
    INNER JOIN BillsUsers bu ON b.BillID = bu.BillID_fkey
    WHERE b.PaidBy = @CurrentDebtor and bu.UserId_fkey = @CurrentUser)
    
    RETURN @AmountPaidByCurrentUser - @AmountPaidByDebtor;
    

    我必须在其中嵌套另一个函数来将金额除以账单被拆分的人数,但如上所述,如果没有 SQLFiddle,我无法从内存中记住这一点。

    【讨论】:

      猜你喜欢
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 2017-02-09
      • 2013-12-06
      • 1970-01-01
      • 2019-04-29
      相关资源
      最近更新 更多