我试着写一个MySQL语句,它会把这些结果带回来:
## Name | Day 0 | Day 1 | Day 2 | Day 3 | Day 4 | Day 5 |
##Jeff | 0 | 3 | 1 | 2 | 1 | 1 |
##Larry | 1 | 1 | 4 | 4 | 1 | 0 |
根据每位员工每天执行的任务数量。
我的数据库表如下:
员工
id
(INT),number
(VARCHAR),name
(VARCHAR),dateStarted
(VARCHAR),
项目
id
(INT),number
(VARCHAR),dateEnded
(DATETIME)
现在我正在使用这个声明:
SELECT
a.name AS "Name",
count(abs(datediff(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))) AS "Day 0",
count(abs(datediff(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))) AS "Day 1",
count(abs(datediff(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))) AS "Day 2",
count(abs(datediff(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))) AS "Day 3",
count(abs(datediff(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))) AS "Day 4",
count(abs(datediff(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))) AS "Day 5"
FROM employee a, project b
WHERE b.number=a.number
AND "Day 0" = 0
AND "Day 1" = 1
AND "Day 2" = 2
AND "Day 3" = 3
AND "Day 4" = 4
AND "Day 5" >= 5
当前输出
以上陈述有效,但由于某种原因,它无法提供上述要求中提到的理想结果。关于如何修复/更改它的任何想法?
修改
如果我拿出来:
AND "Day 0" = 0
AND "Day 1" = 1
AND "Day 2" = 2
AND "Day 3" = 3
AND "Day 4" = 4
AND "Day 5" >= 5
然后打印出来:
## Name | Day 0 | Day 1 | Day 2 | Day 3 | Day 4 | Day 5 |
##Jeff | 9 | 9 | 9 | 9 | 9 | 9 |
答案 0 :(得分:1)
试试这个:
SELECT
emp.name AS '## Name',
(SELECT COUNT(*)
FROM project p JOIN employee e ON p.number = e.number
WHERE e.name = emp.name
AND datediff(str_to_date(p.dateEnded, '%Y-%m-%d'), e.dateStarted) = 0
) AS 'Day 0'
,(SELECT COUNT(*)
FROM project p JOIN employee e ON p.number = e.number
WHERE e.name = emp.name
AND datediff(str_to_date(p.dateEnded, '%Y-%m-%d'), e.dateStarted) = 1
) AS 'Day 1'
,(SELECT COUNT(*)
FROM project p JOIN employee e ON p.number = e.number
WHERE e.name = emp.name
AND datediff(str_to_date(p.dateEnded, '%Y-%m-%d'), e.dateStarted) = 2
) AS 'Day 2'
,(SELECT COUNT(*)
FROM project p JOIN employee e ON p.number = e.number
WHERE e.name = emp.name
AND datediff(str_to_date(p.dateEnded, '%Y-%m-%d'), e.dateStarted) = 3
) AS 'Day 3'
,(SELECT COUNT(*)
FROM project p JOIN employee e ON p.number = e.number
WHERE e.name = emp.name
AND datediff(str_to_date(p.dateEnded, '%Y-%m-%d'), e.dateStarted) = 4
) AS 'Day 4'
,(SELECT COUNT(*)
FROM project p JOIN employee e ON p.number = e.number
WHERE e.name = emp.name
AND datediff(str_to_date(p.dateEnded, '%Y-%m-%d'), e.dateStarted) >= 5
) AS 'Day 5'
FROM employee emp
GROUP BY emp.name
请参阅SQL Fiddle Demo( - 已根据提供的信息对您的数据做出一些假设)。
答案 1 :(得分:1)
试试这个:
SELECT a.name AS "Name",
SUM(noOfDays = 0) AS "Day 0", SUM(noOfDays = 1) AS "Day 1",
SUM(noOfDays = 2) AS "Day 2", SUM(noOfDays = 3) AS "Day 3",
SUM(noOfDays = 4) AS "Day 4", SUM(noOfDays >= 5) AS "Day 5",
COUNT(1) AS "Total Days"
FROM (SELECT a.name, DATEDIFF(DATE(b.dateEnded), DATE(a.dateStarted)) noOfDays
FROM employee a INNER JOIN project b ON b.number = a.number
WHERE b.dateEnded IS NOT NULL
) AS A
GROUP BY a.name;
| NAME | DAY 0 | DAY 1 | DAY 2 | DAY 3 | DAY 4 | DAY 5 | TOTAL DAYS |
|---------|-------|-------|-------|-------|-------|-------|------------|
| ##Jeff | 0 | 3 | 1 | 2 | 1 | 1 | 8 |
| ##Larry | 1 | 1 | 4 | 4 | 1 | 0 | 11 |
答案 2 :(得分:1)
通过执行以下连接语句或其中..
,可以改进以前的解决方案确保在项目上有一个索引(唯一?)(number,dateEnded) 您还可以尝试在employee(number,dateStarted)上添加索引
NULL值通常不是任何索引的一部分(因为它们是null),您可以尝试将该字段的默认值更新为“0000-00-00”,这样它将被索引并可能增加速度。 / p>
试试这个:
SELECT a.name AS "Name",
SUM(noOfDays = 0) AS "Day 0", SUM(noOfDays = 1) AS "Day 1",
SUM(noOfDays = 2) AS "Day 2", SUM(noOfDays = 3) AS "Day 3",
SUM(noOfDays = 4) AS "Day 4", SUM(noOfDays >= 5) AS "Day 5"
FROM (SELECT a.number, a.name, DATEDIFF(DATE(b.dateEnded), DATE(a.dateStarted)) noOfDays
FROM employee a INNER JOIN project b ON (b.number = a.number and b.dateEnded>a.dateStarted)
) AS a
GROUP BY a.name
| NAME | DAY 0 | DAY 1 | DAY 2 | DAY 3 | DAY 4 | DAY 5 |
|---------|-------|-------|-------|-------|-------|-------|
| ##Jeff | 0 | 3 | 1 | 2 | 1 | 1 |
| ##Larry | 1 | 1 | 4 | 4 | 1 | 0 |
答案 3 :(得分:0)
使用之前答案之一的SQL小提琴数据,我试过这个: -
SELECT Sub0.name AS "Name",
SUM(IF(DayDesc = 0 AND DaysCount IS NOT NULL, 1, 0)) AS "Day 0",
SUM(IF(DayDesc = 1 AND DaysCount IS NOT NULL, 1, 0)) AS "Day 1",
SUM(IF(DayDesc = 2 AND DaysCount IS NOT NULL, 1, 0)) AS "Day 2",
SUM(IF(DayDesc = 3 AND DaysCount IS NOT NULL, 1, 0)) AS "Day 3",
SUM(IF(DayDesc = 4 AND DaysCount IS NOT NULL, 1, 0)) AS "Day 4",
SUM(IF(DayDesc = 5 AND DaysCount IS NOT NULL, 1, 0)) AS "Day 5"
FROM
(
SELECT DISTINCT name FROM employee
)Sub0
CROSS JOIN
(
SELECT 0 AS DayMin, 0 AS DayMax, 0 AS DayDesc
UNION
SELECT 1 AS DayMin, 1 AS DayMax, 1 AS DayDesc
UNION
SELECT 2 AS DayMin, 2 AS DayMax, 2 AS DayDesc
UNION
SELECT 3 AS DayMin, 3 AS DayMax, 3 AS DayDesc
UNION
SELECT 4 AS DayMin, 4 AS DayMax, 4 AS DayDesc
UNION
SELECT 5 AS DayMin, 999999999 AS DayMax, 5 AS DayDesc
) Sub1
LEFT OUTER JOIN
(
SELECT a.name, ABS(DATEDIFF(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded)) DaysCount
FROM employee a
INNER JOIN project b
ON b.number = a.number
) Sub2
ON Sub2.DaysCount BETWEEN Sub1.DayMin AND Sub1.DayMax
AND Sub2.name = Sub0.name
GROUP BY Sub0.name
似乎能给出正确的结果而且速度很快。
SQL小提琴: -
http://www.sqlfiddle.com/#!2/db498/84
效率更高(但不能应对没有项目的员工): -
SELECT Sub0.name AS "Name",
SUM(IF(DayDesc = 0, 1, 0)) AS "Day 0",
SUM(IF(DayDesc = 1, 1, 0)) AS "Day 1",
SUM(IF(DayDesc = 2, 1, 0)) AS "Day 2",
SUM(IF(DayDesc = 3, 1, 0)) AS "Day 3",
SUM(IF(DayDesc = 4, 1, 0)) AS "Day 4",
SUM(IF(DayDesc = 5, 1, 0)) AS "Day 5"
FROM
(
SELECT a.name,
CASE ABS(DATEDIFF(STR_TO_DATE(a.dateStarted, '%Y-%m-%d %H:%i:%s'), b.dateEnded))
WHEN 0 THEN 0
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 3
WHEN 4 THEN 4
ELSE 5
END AS DayDesc
FROM employee a
INNER JOIN project b
ON b.number = a.number
) Sub0
GROUP BY Sub0.name
SQL小提琴: -