我正在开发一个Web应用程序。在Web应用程序的数据库中,我有一个名为Daily的表,我每天都在这个表中输入。让我们说它有3列A,B和C.我有另一个名为Monthly的表,其中我每月存储相同的A,B,C值。现在我想要的是,当一个月完成时,即每日表中的条目没有变为30或31,那么在每月表中自动创建一个新行,其A,B和C值将包含每日表中所有值的总和。相应的A,B,C值。 我想知道如何使用SQL来实现这一点,如果没有,还有什么方法可以做到这一点?
答案 0 :(得分:0)
根据您的数据库,操作系统,编程语言等,Gordon Linoff的回应可能是一个很好的方法。
另一种方法是在Daily表上创建一个“触发器”,当插入该月的最后一天的行时,它会自动执行汇总。请注意:触发器很棘手,可能会使维护和复制变得复杂。
为了使解释更容易,我会更具体一点。此外,语法的细节将取决于您具体选择的数据库。这个答案将使用PostgreSQL语法。
这是每日表。我添加了一个列来包含日期,并将其作为主键。
CREATE TABLE daily
(
daily_date date NOT NULL,
a integer NOT NULL,
b integer NOT NULL,
c integer NOT NULL,
CONSTRAINT daily_pkey PRIMARY KEY (daily_date)
);
这是月度表:
CREATE TABLE monthly
(
monthly_date date NOT NULL,
a_sum integer NOT NULL,
b_sum integer NOT NULL,
c_sum integer NOT NULL,
CONSTRAINT monthly_pkey PRIMARY KEY (monthly_date)
);
现在我们创建一个在插入月份的最后一个每日行时调用的过程。在PostgreSQL中,这是一种称为触发器函数的特殊类型。细节因您的数据库而异。
CREATE OR REPLACE FUNCTION summarize_month()
RETURNS trigger AS
$BODY$DECLARE
month_begin DATE :=
make_date(
cast (extract(year from new.daily_date) as integer),
cast (extract(month from new.daily_date) as integer),
1);
month_end DATE :=
month_begin + interval '1 month' - interval '1 day';
BEGIN
INSERT INTO monthly(monthly_date, a_sum, b_sum, c_sum)
(SELECT month_begin, sum(a), sum(b),sum(c)
FROM daily
WHERE daily_date BETWEEN month_begin AND month_end);
return null;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
此过程根据刚刚插入的行的daily_date
计算要汇总的月份的开始和结束日期。然后,它会在monthly
表中插入一个新行,其中包含SELECT
语句计算的汇总数据。
最后,我们将触发器函数附加到daily
表,并告诉它仅在插入月份最后一天的行时执行。
CREATE TRIGGER summarize_daily_to_monthly
AFTER INSERT
ON daily
FOR EACH ROW
WHEN ((date_part('month'::text, new.daily_date) <>
date_part('month'::text, (new.daily_date + 1))))
EXECUTE PROCEDURE summarize_month();
我知道这听起来像一个简单的问题是一个很长的答案。如果您需要进一步澄清,请随时询问。