[英]MySql version 8.0.17 average datediff
In the table stored an a database MySql version 8.0.17
I have these four field set as datetime type
在表中存储了一个数据库MySql version 8.0.17
我将这四个字段设置为datetime type
+---------------------+-----------+---------------------+------------+
| tdate | tigx | tclosed | tcompleted |
+---------------------+-----------+---------------------+------------+
tdate
never null ;字段tdate
从不null ;tigx
it could be null ; tigx
字段可能是null ;tclosed
it could be null ;关闭的字段可能是 null tclosed
tcompleted
it could be null ;完成的字段可能是 null tcompleted
Now I get the average datediff respecting this sequence现在我得到关于这个序列的平均日期差异
tclosed
IS NOT NULL AND tcompleted
IS NOT NULL AND tigx
IS NOT NULL the AVG
is ROUND(AVG(DATEDIFF(tclosed, tdate)),1)
如果tclosed
不是 NULL 并且tcompleted
不是 NULL 并且tigx
不是 NULL ( AVG
是ROUND(AVG(DATEDIFF(tclosed, tdate)),1)
tclosed
IS NULL AND tcompleted
IS NULL AND tigx
IS NULL the AVG
is ROUND(AVG(DATEDIFF(CURDATE(), tdate)),1)
如果tclosed
是 NULL 并且tcompleted
是 NULL 并且tigx
是 NULL ,则AVG
是ROUND(AVG(DATEDIFF(CURDATE(), tdate)),1)
But if at least one of the fields tigx
or tclosed
or tcompleted
is null I have to take the first populated field from tigx
or tclosed
or tcompleted
... and using this first populated field for get the average datediff.但是,如果至少一个字段tigx
或tclosed
或tcompleted
是 null 我必须从tigx
或tclosed
或tcompleted
中获取第一个填充字段......并使用这个第一个填充字段来获取平均 datediff。
Here I am stuck... any suggestion?我在这里卡住了......有什么建议吗?
My query below我在下面的查询
SELECT
tkt,
tdate,
tstate,
tigx,
tclosed,
tcompleted,
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
END AS `avg`
FROM
`tbl_c`
WHERE
NOT ( `tkt` LIKE '%I%' OR `tkt` LIKE '%L%' AND tstate IN ( 'Closed' ) AND tigx IS NULL AND tclosed IS NULL AND tcompleted IS NULL )
ORDER BY
tdate DESC;
UPDATE 2更新 2
SELECT
tkt,
tdate,
tstate,
tigx,
tclosed,
tcompleted,
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
WHEN COALESCE(tclosed,tcompleted,tigx) THEN
ROUND(AVG(DATEDIFF(?????, tdate)),1)
END AS `avg`
FROM
`tbl_c`
WHERE
NOT ( `tkt` LIKE '%I%' OR `tkt` LIKE '%L%' AND tstate IN ( 'Closed' ) AND tigx IS NULL AND tclosed IS NULL AND tcompleted IS NULL )
ORDER BY
tdate DESC;
UPDATE更新
SELECT
tkt,
tdate,
tstate,
tigx,
tclosed,
tcompleted,
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
WHEN COALESCE ( tclosed ) THEN
ROUND( AVG( DATEDIFF( tcompleted, tdate )), 1 )
WHEN COALESCE ( tcompleted ) THEN
ROUND( AVG( DATEDIFF( tigx, tdate )), 1 )
WHEN COALESCE ( tigx ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
END AS `avg`
FROM
`tbl_c`
WHERE
NOT ( `tkt` LIKE '%I%' OR `tkt` LIKE '%L%' AND tstate IN ( 'Closed' ) AND tigx IS NULL AND tclosed IS NULL AND tcompleted IS NULL )
ORDER BY
tdate DESC;
You seem to be struggling with this, following is at least conceptually correct(not sure about the bracketing and outcome)您似乎在为此苦苦挣扎,以下至少在概念上是正确的(不确定括号和结果)
CASE
WHEN ( tclosed IS NOT NULL AND tcompleted IS NOT NULL AND tigx IS NOT NULL ) THEN
ROUND( AVG( DATEDIFF( tclosed, tdate )), 1 )
WHEN ( tclosed IS NULL AND tcompleted IS NULL AND tigx IS NULL ) THEN
ROUND( AVG( DATEDIFF( CURDATE(), tdate )), 1 )
else
ROUND(AVG(DATEDIFF(COALESCE(tclosed,tcompleted,tigx), tdate)),1
END AS `avg`
I have had a go at this one for you, but I have had to make 2 assumptions:我有一个 go 给你,但我不得不做出两个假设:
Given those assumptions are correct, you might like to have a look at this.鉴于这些假设是正确的,您可能想看看这个。 My solution is for you to create a view to handle your date / null logic.我的解决方案是让您创建一个视图来处理您的日期/null 逻辑。 I hope it helps:我希望它有帮助:
/*
Create some test data
need this number generator to create data rows
*/
CREATE OR REPLACE VIEW `number_generator_16` AS
SELECT 0 AS `n`
UNION ALL SELECT 1 AS `1`
UNION ALL SELECT 2 AS `2`
UNION ALL SELECT 3 AS `3`
UNION ALL SELECT 4 AS `4`
UNION ALL SELECT 5 AS `5`
UNION ALL SELECT 6 AS `6`
UNION ALL SELECT 7 AS `7`
UNION ALL SELECT 8 AS `8`
UNION ALL SELECT 9 AS `9`
UNION ALL SELECT 10 AS `10`
UNION ALL SELECT 11 AS `11`
UNION ALL SELECT 12 AS `12`
UNION ALL SELECT 13 AS `13`
UNION ALL SELECT 14 AS `14`
UNION ALL SELECT 15 AS `15`
;
/*Create a table to contain test data*/
DROP TABLE IF EXISTS `a_testdatestdate`;
CREATE TABLE `a_testdatestdate` (
`n` INT(10) SIGNED NOT NULL,
`tdate` DATE NOT NULL,
`tigx` DATE DEFAULT NULL,
`tclosed` DATE DEFAULT NULL,
`tcompleted` DATE DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
/*
(Truncate - if necessary) and repopulate
TRUNCATE TABLE `a_testdatestdate`;
This statement generates a series of 100 rows where
there is always a value in tdate
the other 4 columns are populated with rising date values
Populated with data in columns 2/3/4/(2-3)/(2-4)/(3-4)/(2-3-4)
ASSUMPTIONS:
1) dates have rising values across the columns: tdate <= tigx <= tclosed <= tcompleted
2) all date values are <= CURRENT_DATE
*/
SET @STARTDATE = DATE_ADD(CURRENT_DATE, INTERVAL -200 DAY);
INSERT INTO `a_testdatestdate` (`n`, `tdate`, `tigx`, `tclosed`, `tcompleted`)
SELECT
`n`.`n`,
DATE_FORMAT(DATE_ADD( @STARTDATE, INTERVAL `n`.`n` DAY),"%Y-%m-%d") AS `tDate`
, CASE
WHEN n.n BETWEEN 10 AND 40 THEN DATE_FORMAT(DATE_ADD( @STARTDATE, INTERVAL `n`.`n` + 1 DAY),"%Y-%m-%d")
WHEN n.n BETWEEN 70 AND 80 THEN DATE_FORMAT(DATE_ADD( @STARTDATE, INTERVAL `n`.`n` + 2 DAY),"%Y-%m-%d")
ELSE NULL
END
, CASE
WHEN n.n BETWEEN 30 AND 50 THEN DATE_FORMAT(DATE_ADD( @STARTDATE, INTERVAL `n`.`n` + 3 DAY),"%Y-%m-%d")
WHEN n.n BETWEEN 90 AND 100 THEN DATE_FORMAT(DATE_ADD( @STARTDATE, INTERVAL `n`.`n` + 4 DAY),"%Y-%m-%d")
ELSE NULL
END
, CASE
WHEN n.n BETWEEN 35 AND 60 THEN DATE_FORMAT(DATE_ADD( CURRENT_DATE, INTERVAL `n`.`n` + 6 DAY),"%Y-%m-%d")
WHEN n.n BETWEEN 70 AND 80 THEN DATE_FORMAT(DATE_ADD( CURRENT_DATE, INTERVAL `n`.`n` + 7 DAY),"%Y-%m-%d")
ELSE NULL
END
FROM (
SELECT
((`hi`.`n` << 4) | `lo`.`n`) AS `n`
FROM (`number_generator_16` `lo`
JOIN `number_generator_16` `hi`)
) `n`
WHERE n.n <100
;
/*
review test data
SELECT * FROM a_testdatestdate;
Create a view to handle your logic around dates and NULL values
*/
DROP VIEW IF EXISTS v_testdatestdate;
CREATE OR REPLACE VIEW v_testdatestdate AS SELECT
n,
tdate,
CASE
WHEN ISNULL(tigx) AND ISNULL(tclosed) AND ISNULL(tcompleted) THEN CURRENT_DATE
WHEN NOT ISNULL(tigx) AND NOT ISNULL(tclosed) AND NOT ISNULL(tcompleted) THEN `tclosed`
ELSE LEAST(IFNULL(tigx, CURRENT_DATE), IFNULL(tclosed, CURRENT_DATE), IFNULL(tcompleted, CURRENT_DATE))
END AS dte
FROM a_testdatestdate;
/*
Then generate your averages from a statement like this
I have left the statement in this state so you can unpick it to suit your requirements
*/
SELECT
ROUND(AVG(`DateDiff`),1)
FROM
(
SELECT
DATEDIFF(dte, tdate) AS `DateDiff`
FROM v_testdatestdate V
) B
;
--> Result = 57.9 in this case. --> 在这种情况下,结果 = 57.9。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.