0

我有一个小应用程序(PHP/MySQL)来管理公寓。有一张condos桌子,apartments一张桌子,一张owners桌子和一张account桌子。

account表中,我有字段month_paidyear_paid(除其他外)。

每次有人支付月费时,表格都会更新月数和年数。

这是一些示例表结构:

condos桌子:

+----+------------+---------+
| id | condo_name | address |
+----+------------+---------+

apartments桌子:

+----+----------------+----------+
| id | apartment_name | condo_id |
+----+----------------+----------+

owners桌子:

+----+--------------+------------+
| id | apartment_id | owner_name |
+----+--------------+------------+

account桌子:

+----+----------+----------+------------+-----------+
| id | owner_id | condo_id | month_paid | year_paid |
+----+----------+----------+------------+-----------+

因此,如果我在帐户表中有这样的记录,则表示该所有者在 2012 年 8 月付款:

+----+----------+----------+------------+-----------+
| id | owner_id | condo_id | month_paid | year_paid |
+----+----------+----------+------------+-----------+
|  1 |        1 |        1 |          8 |      2012 |
+----+----------+----------+------------+-----------+

我想知道的是如何进行 SQL 查询(使用 PHP)来获取欠债三个月或更长时间的业主,或者换句话说,是过去三个月或更长时间未支付费用的业主。

如果可能,数据应按公寓分组,如下所示:

CONDO XPTO:
Owner 1: 3 months debt
Onwer 2: 5 months debt

CONDO BETA
Owner 1: 4 months debt
Onwer 2: 6 months debt

谢谢

4

6 回答 6

4

您需要编写如下查询:

SELECT
    *
FROM
    owners
JOIN
    account
ON
    owners.id = account.owners_id
WHERE
    CONCAT( account.year_paid , '-' , account.month_paid , '-01') <= DATE_ADD( NOW(), INTERVAL -3 MONTH );

可悲的是,这就是我所能提供的所有信息。如果您可以显示更详细的表格结构,我可以为您提供更多帮助。

于 2012-12-27T11:15:05.393 回答
1

以这种方式存储它会让你自己变得更难。现在您需要自己计算以月为单位的差异。您不能只检查月份,因为例如在 1 月份,您还需要将年份考虑在内。

SELECT *
FROM owners
JOIN account ON owners.Id=account.ownersId
WHERE (    
  account.year_paid = year(now)
  AND (
    month(now)-account.month_paid>=3
  )
) OR (
  account.year_paid = year(now)-1
  AND (
    month(now)>=3
    OR (
      account.month_paid - month(now) <= 10
      AND month(now) = 1
    )
    OR (
      account.month_paid - month(now) <= 11
      AND month(now) = 2
    )
  )
) OR (
  account.year_paid < year(now)-1
)

最好将 lastpaid 时间存储在一个列中,datetime这样您就可以使用日期函数。

于 2012-12-27T11:23:47.450 回答
0

如果我理解正确,那么您有两个不同的字段用于蛾和年份。为什么?如果你有一个字段说paid_date这个查询对你有用

SELECT owner_id from account WHERE NOW()>DATE_ADD(paid_date, INTERVAL 3 MONTH)

如果您可以更改字段,那么对不起。我希望这是有帮助的。

UPD: 那么我建议您在查询中连接两个字段(yearmonth),使其在YYYY-MM-DD格式上看起来像真实日期,并在DATE_ADD函数而不是paid_date字段中使用它

于 2012-12-27T11:26:26.227 回答
0

试试这个,

select o.owner_name,c.condo_name   from owners o join account a join condos c
on o.id=a.owner_id  and c.id =a.condo_id  where year(curdate())=a.year_paid 
and  a.month_paid<month(curdate())-3
于 2012-12-27T12:01:28.483 回答
0

修复您的帐户表。s 是可选的DROP COLUMN,如果它们有依赖关系,您可能希望保留它们。

ALTER TABLE account ADD COLUMN date_paid DATETIME;
UPDATE account SET date_paid = CONCAT(year_paid,'-',month_paid,'-01');
--ALTER TABLE account DROP COLUMN year_paid;
--ALTER TABLE account DROP COLUMN month_paid;

这就是您获取数据的方式。LEFT OUTER JOIN如果您缺少任何所有者或公寓记录,我使用了 s。

SELECT c.condo_name, 
o.owner_name, 
min(PERIOD_DIFF(DATE_FORMAT(now(), '%Y%m'), DATE_FORMAT(date_paid, '%Y%m'))) min_months_debt 
FROM account a
LEFT OUTER JOIN condos c ON (c.id = a.condo_id)
LEFT OUTER JOIN owners o ON (a.owner_id = o.id)
WHERE a.date_paid <= DATE_ADD(NOW(), INTERVAL -3 MONTH)
GROUP BY c.condo_name, o.owner_name
ORDER BY c.condo_name

PS 以上仅适用于已支付至少一笔款项的公寓业主。如果您想查看从未付款的公寓业主,那么您将不得不将公寓与帐户表之外的业主相关联。或者,当您将公寓与所有者关联时,您可能会创建一个帐户记录,在这种情况下您没有问题。

于 2012-12-27T12:49:01.200 回答
0

我还没有看到任何真正产生你正在寻找的答案。以下通过计算当前月份减去最近的付款日期来计算债务月份。然后它将结果连接成一个字符串:

select c.condo_name, o.owner_name, 
       cast(YEAR(now)*12+MONTH(now)) - MAX(year_paid*12+month_paid) as varchar(255)), ' month(s) debt'
from account a join
     owners o
     on o.id = a.owner_id join
     condos c
     on c.id = a.condo_id
group by c.condo_name,, o.owner_name
order by 1, 2

如果您只想要拖欠付款人,则添加一个where条款以达到以下效果:

where YEAR(now)*12+MONTH(now)) - MAX(year_paid*12+month_paid)  > 1

因为您没有付款月份的日期,所以您可能会错过一些临界条件。

于 2012-12-27T14:33:36.807 回答