为时间表创建视图
Create a view for a timesheet
我正在处理以下 2 个表:
CREATE TABLE Consultant_Alloc (
project_no number(6),
activity_no number(4) NOT NULL,
consultant_id char(7) NOT NULL UNIQUE,
allocated_hours number(3) NOT NULL,
hours_worked number(3),
-- SUM(Consultant_Alloc.allocated_hours)
CONSTRAINT pk_project_activity_consultant PRIMARY KEY (project_no, activity_no, consultant_id),
CONSTRAINT fk_consultant_id FOREIGN KEY (consultant_id) REFERENCES Consultant (consultant_id)
ON DELETE CASCADE,
CONSTRAINT fk_project_no_activity_no_budget FOREIGN KEY (project_no, activity_no, budget) REFERENCES Activity (project_no, activity_no, budget_hours)
ON DELETE CASCADE,
);
CREATE TABLE Activity (
activity_no number(4) NOT NULL,
activity_name varchar2(50),
project_no number(6) NOT NULL,
allocated_hours number(3) CHECK (allocated_hours > 0),
start_date date,
end_date date,
comp_date date,
CONSTRAINT pk_Activity_project_no_activity_no PRIMARY KEY (project_no, activity_no), -- Each activity must be unique
CONSTRAINT fk_Activity_project FOREIGN KEY (project_no) REFERENCES Project (project_no)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT ck_dates CHECK (start_date >= end_date)
);
我需要创建一个 oracle SQL 视图,详细说明上一个日历月的项目工作小时数。我正在为我的业务学习这一点,并希望得到一些关于如何执行此操作的指示,因为我不知道如何引用上一个日历月的所有项目。
谢谢
CREATE VIEW time_sheet
AS SELECT CA.consultant_id CONSULTANT, A.project_no PROJECT, A.activity_no ACTIVITY, CA.hours_worked HOURS
FROM Consultant_Alloc CA, Activity A
WHERE -- in previous calendar month
GROUP BY CA.consultant_id
这就是我要去的地方。
诀窍在于确定给定的日期范围是否与 start_date
和 end_date
的范围重叠,对吗? (或者 comp_date
可以晚一点吗?)我假设范围 start_date
和 end_date
就足够了;如果你需要 comp_date
你应该可以插入它。
确定相交日期的公式如下所示:
(StartA <= EndB) and (EndA >= StartB)
在您的情况下,StartA
将是 start_date
,而 EndA
将是 end_date
,而 StartB
将是上个月的第一天, EndB
将是上个月的最后一天。但是,由于 Oracle 日期包含时间部分,我要说 EndB
是 当前 月份的第一天,并使用 <
而不是<=
.
所以要获取上个月发生的所有活动:
SELECT activity_no, activity_name, project_no, allocated_hours
FROM Activity
WHERE start_date < TRUNC(sysdate, 'MONTH')
AND end_date >= TRUNC(ADD_MONTHS(sysdate, -1), 'MONTH');
如果我想获得分配给特定项目的时间,我可以执行以下操作:
SELECT project_no, SUM(allocated_hours)
FROM Activity
WHERE start_date < TRUNC(sysdate, 'MONTH')
AND end_date >= TRUNC(ADD_MONTHS(sysdate, -1), 'MONTH');
GROUP BY project_no;
不过,这里的困难在于 activity 没有具体的日期;看起来它可以跨越不同的月份。这使得查找在特定月份 中分配给项目的小时数 即使不是不可能也很困难。我所能做的就是找到分配给给定项目的小时数,其中 activity 的日期范围与该月的天数范围相交。我认为,对于给定的 activity,您应该有几个小时的 log table,例如,
CREATE TABLE activity_log
( activity_no NUMBER(4) NOT NULL
, consultant_id CHAR(7) NOT NULL
, log_hours NUMBER(3) CHECK (log_hours> 0)
, log_dt DATE DEFAULT SYSDATE NOT NULL
);
然后,我认为只有到那时,您才能获得给定月份的项目工作小时数报告:
SELECT a.project_no, SUM(al.log_hours)
FROM activity a INNER JOIN activity_log al
ON a.activity_no = al.activity_no
WHERE TRUNC(log_dt, 'MONTH') = TRUNC(ADD_MONTHS(SYSDATE, -1), 'MONTH')
GROUP BY a.project_no;
这样的 table 也能让您得到顾问的细分:
SELECT a.project_no, al.consultant_id, SUM(al.log_hours)
FROM activity a INNER JOIN activity_log al
ON a.activity_no = al.activity_no
WHERE TRUNC(log_dt, 'MONTH') = TRUNC(ADD_MONTHS(SYSDATE, -1), 'MONTH')
GROUP BY a.project_no, al.consultant_id;
顺便说一下,在 Oracle 中没有任何理由在 VARCHAR2
上使用 CHAR
,除非在创建 1 个字符的列时节省击键(例如,CHAR(1)
而不是 VARCHAR2(1)
).
我正在处理以下 2 个表:
CREATE TABLE Consultant_Alloc (
project_no number(6),
activity_no number(4) NOT NULL,
consultant_id char(7) NOT NULL UNIQUE,
allocated_hours number(3) NOT NULL,
hours_worked number(3),
-- SUM(Consultant_Alloc.allocated_hours)
CONSTRAINT pk_project_activity_consultant PRIMARY KEY (project_no, activity_no, consultant_id),
CONSTRAINT fk_consultant_id FOREIGN KEY (consultant_id) REFERENCES Consultant (consultant_id)
ON DELETE CASCADE,
CONSTRAINT fk_project_no_activity_no_budget FOREIGN KEY (project_no, activity_no, budget) REFERENCES Activity (project_no, activity_no, budget_hours)
ON DELETE CASCADE,
);
CREATE TABLE Activity (
activity_no number(4) NOT NULL,
activity_name varchar2(50),
project_no number(6) NOT NULL,
allocated_hours number(3) CHECK (allocated_hours > 0),
start_date date,
end_date date,
comp_date date,
CONSTRAINT pk_Activity_project_no_activity_no PRIMARY KEY (project_no, activity_no), -- Each activity must be unique
CONSTRAINT fk_Activity_project FOREIGN KEY (project_no) REFERENCES Project (project_no)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT ck_dates CHECK (start_date >= end_date)
);
我需要创建一个 oracle SQL 视图,详细说明上一个日历月的项目工作小时数。我正在为我的业务学习这一点,并希望得到一些关于如何执行此操作的指示,因为我不知道如何引用上一个日历月的所有项目。
谢谢
CREATE VIEW time_sheet
AS SELECT CA.consultant_id CONSULTANT, A.project_no PROJECT, A.activity_no ACTIVITY, CA.hours_worked HOURS
FROM Consultant_Alloc CA, Activity A
WHERE -- in previous calendar month
GROUP BY CA.consultant_id
这就是我要去的地方。
诀窍在于确定给定的日期范围是否与 start_date
和 end_date
的范围重叠,对吗? (或者 comp_date
可以晚一点吗?)我假设范围 start_date
和 end_date
就足够了;如果你需要 comp_date
你应该可以插入它。
确定相交日期的公式如下所示:
(StartA <= EndB) and (EndA >= StartB)
在您的情况下,StartA
将是 start_date
,而 EndA
将是 end_date
,而 StartB
将是上个月的第一天, EndB
将是上个月的最后一天。但是,由于 Oracle 日期包含时间部分,我要说 EndB
是 当前 月份的第一天,并使用 <
而不是<=
.
所以要获取上个月发生的所有活动:
SELECT activity_no, activity_name, project_no, allocated_hours
FROM Activity
WHERE start_date < TRUNC(sysdate, 'MONTH')
AND end_date >= TRUNC(ADD_MONTHS(sysdate, -1), 'MONTH');
如果我想获得分配给特定项目的时间,我可以执行以下操作:
SELECT project_no, SUM(allocated_hours)
FROM Activity
WHERE start_date < TRUNC(sysdate, 'MONTH')
AND end_date >= TRUNC(ADD_MONTHS(sysdate, -1), 'MONTH');
GROUP BY project_no;
不过,这里的困难在于 activity 没有具体的日期;看起来它可以跨越不同的月份。这使得查找在特定月份 中分配给项目的小时数 即使不是不可能也很困难。我所能做的就是找到分配给给定项目的小时数,其中 activity 的日期范围与该月的天数范围相交。我认为,对于给定的 activity,您应该有几个小时的 log table,例如,
CREATE TABLE activity_log
( activity_no NUMBER(4) NOT NULL
, consultant_id CHAR(7) NOT NULL
, log_hours NUMBER(3) CHECK (log_hours> 0)
, log_dt DATE DEFAULT SYSDATE NOT NULL
);
然后,我认为只有到那时,您才能获得给定月份的项目工作小时数报告:
SELECT a.project_no, SUM(al.log_hours)
FROM activity a INNER JOIN activity_log al
ON a.activity_no = al.activity_no
WHERE TRUNC(log_dt, 'MONTH') = TRUNC(ADD_MONTHS(SYSDATE, -1), 'MONTH')
GROUP BY a.project_no;
这样的 table 也能让您得到顾问的细分:
SELECT a.project_no, al.consultant_id, SUM(al.log_hours)
FROM activity a INNER JOIN activity_log al
ON a.activity_no = al.activity_no
WHERE TRUNC(log_dt, 'MONTH') = TRUNC(ADD_MONTHS(SYSDATE, -1), 'MONTH')
GROUP BY a.project_no, al.consultant_id;
顺便说一下,在 Oracle 中没有任何理由在 VARCHAR2
上使用 CHAR
,除非在创建 1 个字符的列时节省击键(例如,CHAR(1)
而不是 VARCHAR2(1)
).