简体   繁体   English

MySql 版本 8.0.17 平均 datediff

[英]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 |
+---------------------+-----------+---------------------+------------+
  • the field tdate never null ;字段tdate从不null
  • the field tigx it could be null ; tigx字段可能是null
  • the field tclosed it could be null ;关闭的字段可能是 null tclosed
  • the field tcompleted it could be null ;完成的字段可能是 null tcompleted

Now I get the average datediff respecting this sequence现在我得到关于这个序列的平均日期差异

  1. If 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 ( AVGROUND(AVG(DATEDIFF(tclosed, tdate)),1)
  2. If 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 ,则AVGROUND(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.但是,如果至少一个字段tigxtclosedtcompleted是 null 我必须从tigxtclosedtcompleted中获取第一个填充字段......并使用这个第一个填充字段来获取平均 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 给你,但我不得不做出两个假设:

  1. Dates have rising values across the columns: tdate <= tigx <= tclosed <= tcompleted日期在各列中具有上升值:tdate <= tigx <= tclosed <= tcompleted
  2. All date values are <= CURRENT_DATE所有日期值均 <= CURRENT_DATE

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM