INT comparison without WHERE statement

后端 未结 4 1940
别那么骄傲
别那么骄傲 2021-01-16 22:11

Im trying to write a MySQL statement that will bring me back these results:

## Name | Day 0 | Day 1 | Day 2 | Day 3 | Day 4 | Day 5 |
##Jeff  |   0   |    3          


        
相关标签:
4条回答
  • 2021-01-16 22:36

    The previous solution could be improved by doing the following join statement or where..

    Make sure to have an index ( unique ? ) on project (number,dateEnded) You could also try to add index on employee (number, dateStarted)

    NULL values are usually not part of any indexes (as they are null), you could try updating the default value of that field to '0000-00-00', this way it would get indexed and potentially add speed.

    Try this:

    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
    

    Check the SQL FIDDLE DEMO

    |    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 |
    
    0 讨论(0)
  • 2021-01-16 22:48

    Using the SQL fiddle data from one of the previous answers, I have tried this:-

    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
    

    Seems to give the right results and be quite fast.

    SQL fiddle here:-

    http://www.sqlfiddle.com/#!2/db498/84

    Bit more efficient (but doesn't cope with employees who have no projects):-

    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 fiddle here:-

    http://www.sqlfiddle.com/#!2/db498/89

    0 讨论(0)
  • 2021-01-16 22:55

    Try this:

    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;
    

    Check the SQL FIDDLE DEMO

    |    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 |
    
    0 讨论(0)
  • 2021-01-16 23:00

    Try this:

    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
    

    See SQL Fiddle Demo (- have made some assumptions on your data based on the info provided).

    0 讨论(0)
提交回复
热议问题