也许有人可以对我一整天都在努力的声明有所了解:)
我有3张桌子
度假
holidayID | userID | dateFrom | dateTo
1 | 1 | 2012-01-01 | 2012-01-01
2 | 1 | 2012-01-15 | 2012-01-20
状态
statusID | holidayID | statusText
1 | 1 | accepted
2 | 2 | declined
UserSettings
id | userID | HolidaysAllowed
1 | 1 | 20
我要做的是获得以下结果
结果
HolidaysAllowed | HolidaysLeft (Allowed - Taken) | HolidaysTaken (Sum of Holidays)
20 | 19 | 1
如果我没有说明状态,我可以获得所有三列 - 这是我最接近的
SELECT
IFNULL(SUM( IF( h.dateTo = h.dateFrom, 1, DATEDIFF( h.dateTo, h.dateFrom ) ) ), 0) AS holidaysTaken,
IFNULL(us.HolidaysAllowed - ( SUM( IF( h.DateTo = h.DateFrom, 1, DATEDIFF( h.DateTo, h.dateFrom ) ) ) ), 0) AS holidaysLeftover,
us.HolidaysAllowed
FROM userSettings us
LEFT JOIN holiday h
ON h.userID = 1
JOIN status s
ON s.holidayID = h.holidayID AND s.statusID = 1
WHERE
us.userID = 1
GROUP BY h.userID;
主要问题是,如果没有statusID = 2的假期,那么结果列1& 2是0(这是正确的)但第3列(HolidaysAllowed)是NULL(不正确,因为它需要始终从表UserSettings返回值)。上述查询仅在至少有1个记录(假日)状态正确时才返回正确的响应...我做错了什么? :)
它只是让我疯了:)在此先感谢任何帮助!非常感谢!
更新
感谢所有评论的人......预期结果如下 获取状态= 1(即已接受)的所有假期,然后根据允许的假期计算假期统计数据。即。
总共20天,接受1个假期=剩余19天
再次感谢
答案 0 :(得分:3)
SELECT u.userID, u.HolidaysAllowed,
u.holidaysAllowed -
COALESCE(
(SELECT SUM( DATEDIFF( h1.dateTo, h1.dateFrom) + 1)
FROM holiday h1
INNER JOIN status s1
ON s1.holidayID = h1.holidayID
WHERE h1.userID = u.userID
AND s1.statusID = 1
), 0) AS HolidaysLeft,
COALESCE(
(SELECT SUM( DATEDIFF( h2.dateTo, h2.dateFrom) + 1)
FROM holiday h2
INNER JOIN status s2
ON s2.holidayID = h2.holidayID
WHERE h2.userID = u.userID
AND s2.statusID = 1
), 0) AS HolidaysTaken
FROM userSettings u
;
答案 1 :(得分:2)
以下查询不会考虑周末。
Click here to view the demo in SQL Fiddle.
脚本:
CREATE TABLE Holiday
(
holidayid INT NOT NULL AUTO_INCREMENT
, userid VARCHAR(20) NOT NULL
, dateFrom DATETIME NOT NULL
, dateTo DATETIME NOT NULL
, PRIMARY KEY(holidayid)
);
CREATE TABLE Status
(
id INT NOT NULL AUTO_INCREMENT
, holidayid INT NOT NULL
, statusid INT NOT NULL
, PRIMARY KEY(id)
);
CREATE TABLE UserSettings
(
id INT NOT NULL AUTO_INCREMENT
, userid INT NOT NULL
, HolidaysAllowed INT NOT NULL
, PRIMARY KEY(id)
);
INSERT INTO Holiday (userid, dateFrom, dateTo) VALUES
(1, '2012-04-01', '2012-04-03'),
(2, '2012-04-04', '2012-04-05'),
(2, '2012-04-07', '2012-04-09'),
(3, '2012-04-09', '2012-04-12'),
(3, '2012-04-16', '2012-04-16'),
(1, '2012-04-19', '2012-04-22');
INSERT INTO Status (holidayid, statusid) VALUES
(1, 2),
(2, 1),
(3, 1),
(4, 1),
(5, 2),
(6, 2);
INSERT INTO UserSettings (userid, HolidaysAllowed) VALUES
(1, 5),
(2, 10),
(3, 7),
(4, 6);
SELECT u.userid
, u.HolidaysAllowed
, u.HolidaysAllowed - COALESCE(hol.HolidaysTaken, 0) AS HolidaysLeft
, COALESCE(hol.HolidaysTaken, 0) AS HolidaysTaken
FROM
(
SELECT h.userid
, ABS(SUM(
CASE
WHEN statusid = 1 THEN DATEDIFF(dateTo, dateFrom) + 1
ELSE 0 END
)) HolidaysTaken
FROM UserSettings us
LEFT OUTER JOIN Holiday h
ON us.userid = h.userid
LEFT OUTER JOIN Status s
ON s.holidayid = h.holidayid
GROUP BY h.userid
) hol
RIGHT OUTER JOIN UserSettings u
ON u.userid = hol.userid;
输出:
USERID HOLIDAYSALLOWED HOLIDAYSLEFT HOLIDAYSTAKEN
------ --------------- ------------ -------------
1 5 5 0
2 10 5 5
3 7 3 4
4 6 6 0
答案 2 :(得分:0)
SELECT B.HolidaysAllowed AS HolidaysAllowed,
B.HolidaysAllowed-A.HolidaysTaken AS HolidaysLeft,
A.HolidaysTaken AS HolidaysTaken
FROM
(
SELECT A.userID,SUM(CASE WHEN DATEDIFF(A.dateTo,A.dateFom)=0
THEN 1
ELSE DATEDIFF(A.dateTo,A.dateFom)
) AS HolidaysTaken
FROM Holiday A,Status B
WHERE A.holidayID = B.holidayID
AND A.statusText='accepted'
GROUP BY useID
) A,
UserSettings B
WHERE A.userID = B.userID;