我正在处理以下两个表格:
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
这就是我要去的地方。
答案 0 :(得分:0)
诀窍在于确定给定的日期范围是否与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
是当前月的第一天,并使用<
而不是{{1 }}
所以要完成上个月发生的所有活动:
<=
如果我想将时间分配给特定项目,我可以执行以下操作:
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');
但是,这里的困难在于没有特定的活动日期;看起来它可以跨越不同的月份。这使得查找在特定月份中分配给项目的小时数很困难,如果不是不可能的话。我所能做的就是找到分配给给定项目的小时数,其中活动的日期范围与该月的天数范围相交。我认为,对于给定的活动,您应该有一个 log 表数小时,例如,
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;
然后,我认为只有这样,您才能获得某个月内项目工作时间的报告:
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;
顺便说一下,除了在创建1个字符的列(例如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;
而不是CHAR
时保存键击时,除了VARCHAR2
之外,从来没有任何理由在Oracle中使用CHAR(1)
。 VARCHAR2(1)
)。