2 回答
TA贡献1993条经验 获得超5个赞
尽管您对表结构的处理方式似乎有些无效,但我会尝试解决您的问题,忽略这一点。
因此,假设您有包含以下内容的 PHP 变量:
$target_month = '08';
$target_year = date("Y");
我们想要收集年份,因为我们不希望 sql 假设 2019 年 8 月与 2018 年 8 月相同并将它们混合。
调整到您当前的结构,我首先要为每个项目获取本月最后一笔交易的子查询。我们使用 GROUP BY 语句和 MAX() 聚合函数的组合来做到这一点。
SELECT medID, MAX(medTransacID) AS lastTransacID
FROM medicinetransac
WHERE MONTH(transacDate) = {$target_month} AND YEAR(transacDate) = {$target_year}
GROUP BY medId
请注意,我们没有获得最后一个日期(因为我们每个日期可以有多个交易),因此我们获得了最高的交易 ID。只要确保它是自动递增的。
现在,要获取上个月的数据,需要做一些假设。我们需要在最后这一个月之前一个月的数据,或最后一笔交易?有很大的不同,因为如果我们上个月没有交易怎么办?如果最后一次购买商品是在 5 个月前怎么办?我们用那个?还是我们显示空白?对于此示例,我将假设您想要本月之前的最后一笔交易,无论是上个月还是 3 个月前。
SELECT medId, transacDate, transacCurrentBal
FROM medicinetransac a
WHERE medTransacID = (
SELECT MAX(medTransacID) FROM medicinetransac b
WHERE MONTH(transacDate) < {$target_month}
AND YEAR(transacDate) <= {$target_year}
AND b.medId = a.medId
LIMIT 1
)
因此,在该查询中,我们提取在本月之前的任何日期找到的最大交易 ID。请注意我如何使用 < 和 <= 作为日期。
我们现在可以像这样构建这个大查询:
SELECT
med.medID,
med.medDescription,
tmd.transacType,
topmt.transacCurrentBal AS beginningBalance,
topmt.transacDate AS begginingBalanceDate,
tmd.transacDate AS lastTransactionDate,
tmd.transacQuantity AS lastTransactionQuantity
FROM medicine med
LEFT JOIN (
SELECT medID, MAX(medTransacID) AS lastTransacID
FROM medicinetransac
WHERE MONTH(transacDate) = {$target_month} AND YEAR(transacDate) = {$target_year}
GROUP BY medId
) table_of_last_transaction_ids tolti ON med.medID = tolti.medID
LEFT JOIN medicinetransac target_month_data tmd ON tmd.medTransacID = tolti.medTransacId
LEFT JOIN (
SELECT medId, transacDate, transacCurrentBal
FROM medicinetransac a
WHERE medTransacID = (
SELECT MAX(medTransacID) FROM medicinetransac b
WHERE MONTH(transacDate) < {$target_month}
AND YEAR(transacDate) <= {$target_year}
AND b.medId = a.medId
LIMIT 1
)
) table_of_previous_months_transaction topmt ON topmt.medId = med.medId
但是,对此有一些注意事项。子查询通常很慢,如果您使用的是更新版本的 mysql,我建议您查看window functions。如果最后一个子查询不起作用,请考虑使用左连接而不是嵌套选择。我这样做只是为了向您展示差异。
另外,一些提示;
尽量避免使用非字母字符作为列名和别名
使表和列更具描述性
使用数据库时坚持使用 underscore_notation(更干净)
避免表中的冗余。注意 transacType 有多么冗余?为什么不使用两个单独的表进行输入/输出交易?
希望这会帮助你。祝你好运!
- 2 回答
- 0 关注
- 183 浏览
添加回答
举报