Presented with the following snippet of SQL:
CASE
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 30) THEN '>= 30 (inclusive)'
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 20) THEN '>= 20 (inclusive)'
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 10) THEN '>= 10 (inclusive)'
ELSE '< 10'
END
(The full query is below, the snippet above is just to highlight the problem)
The above current results in exclusive matches:
(30 <= date_diff) = '>= 30'
(20 <= date_diff <= 30) = '>= 20'
(10 <= date_diff <= 20) = '>= 10'
(date_diff < 10) = '< 10'
But what I need is inclusive matches:
(30 <= date_diff <= 0) = '>= 30'
(20 <= date_diff <= 0) = '>= 20'
(10 <= date_diff <= 0) = '>= 10'
(date_diff < 10) = '< 10'
So - if a record is older than 30 years, it must be categorized in in >= 10
, >= 20
as well as >= 30
, and so on.
FULL QUERY
SELECT
COUNT(*) AS `RecordCount`, `ExistingPlanned`, `ResponsibleOrg`, `StartDateTCDR`, `EndDateTCDR`, `SpecificEndDate`, `ResponsibleOrgOut`,
(CASE
WHEN (`EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 0) THEN '2018-12-31'
WHEN (`EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 1) THEN '-'
ELSE `EndDateTCDR`
END) AS `EndDate`,
(CASE
WHEN (`StartDateTCDR` < '1001-01-01') THEN '-'
ELSE `StartDateTCDR`
END) AS `StartDate`,
(CASE
WHEN (`StartDateTCDR` < '1001-01-01') THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 1) THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 0) THEN (
CASE
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 30) THEN '>= 30 (inclusive)'
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 20) THEN '>= 20 (inclusive)'
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 10) THEN '>= 10 (inclusive)'
ELSE '< 10'
END
)
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` > '1001-01-01') THEN (
CASE
WHEN (YEAR(`EndDateTCDR`) - YEAR(`StartDateTCDR`) - (DATE_FORMAT(`EndDateTCDR`, '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 30) THEN '>= 30 (inclusive)'
WHEN (YEAR(`EndDateTCDR`) - YEAR(`StartDateTCDR`) - (DATE_FORMAT(`EndDateTCDR`, '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 20) THEN '>= 20 (inclusive)'
WHEN (YEAR(`EndDateTCDR`) - YEAR(`StartDateTCDR`) - (DATE_FORMAT(`EndDateTCDR`, '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 10) THEN '>= 10 (inclusive)'
ELSE '< 10'
END
)
END) AS `TCDRLength`,
(CASE
WHEN (`StartDateTCDR` < '1001-01-01') THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 1) THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 0) THEN (
ROUND((DATEDIFF('2018-12-31', `StartDateTCDR`) / 365), 2)
)
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` > '1001-01-01') THEN (
ROUND((DATEDIFF(`EndDateTCDR`, `StartDateTCDR`) / 365), 2)
)
END) AS `ActualLength`
FROM `data_records`
LEFT JOIN `RespOrgLUT`
ON `ResponsibleOrgIn` = `ResponsibleOrg`
GROUP BY `ExistingPlanned`, `ResponsibleOrg`, `StartDateTCDR`, `EndDateTCDR`, `SpecificEndDate`, `ResponsibleOrgOut`, `StartDate`, `EndDate`, `ActualLength`, `TCDRLength`
ORDER BY `ResponsibleOrg` ASC, `RecordCount` DESC, `ResponsibleOrgOut` ASC, `ActualLength` DESC, `TCDRLength` DESC
LIMIT 0, 2000
EDIT 1
Using the suggestion by @Barmar, my query now looks like this, resulting in an error: #1248 - Every derived table must have its own alias
, so I clearly implemented it wrong, so any further assistance will be appreciated.
SELECT
COUNT(*) AS `RecordCount`, `ExistingPlanned`, `ResponsibleOrg`, `StartDateTCDR`, `EndDateTCDR`, `SpecificEndDate`, `ResponsibleOrgOut`,
(CASE
WHEN (`EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 0) THEN '2018-12-31'
WHEN (`EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 1) THEN '-'
ELSE `EndDateTCDR`
END) AS `EndDate`,
(CASE
WHEN (`StartDateTCDR` < '1001-01-01') THEN '-'
ELSE `StartDateTCDR`
END) AS `StartDate`,
(CASE
WHEN (`StartDateTCDR` < '1001-01-01') THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 1) THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 0) THEN (
CASE
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 30) THEN '>= 30 (inclusive)'
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 20) THEN '>= 20 (inclusive)'
WHEN (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 10) THEN '>= 10 (inclusive)'
ELSE '< 10'
END
)
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` > '1001-01-01') THEN (
CASE
WHEN (YEAR(`EndDateTCDR`) - YEAR(`StartDateTCDR`) - (DATE_FORMAT(`EndDateTCDR`, '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 30) THEN '>= 30 (inclusive)'
WHEN (YEAR(`EndDateTCDR`) - YEAR(`StartDateTCDR`) - (DATE_FORMAT(`EndDateTCDR`, '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 20) THEN '>= 20 (inclusive)'
WHEN (YEAR(`EndDateTCDR`) - YEAR(`StartDateTCDR`) - (DATE_FORMAT(`EndDateTCDR`, '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 10) THEN '>= 10 (inclusive)'
ELSE '< 10'
END
)
END) AS `TCDRLength`,
(CASE
WHEN (`StartDateTCDR` < '1001-01-01') THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 1) THEN '-'
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` < '1001-01-01' AND `SpecificEndDate` = 0) THEN (
ROUND((DATEDIFF('2018-12-31', `StartDateTCDR`) / 365), 2)
)
WHEN (`StartDateTCDR` > '1001-01-01' AND `EndDateTCDR` > '1001-01-01') THEN (
ROUND((DATEDIFF(`EndDateTCDR`, `StartDateTCDR`) / 365), 2)
)
END) AS `ActualLength`
FROM `data_records`
LEFT JOIN `RespOrgLUT` ON `ResponsibleOrgIn` = `ResponsibleOrg`
LEFT JOIN (
SELECT `category`, COUNT(*)
FROM `data_records` dr
JOIN (
SELECT '< 10' AS `category`
UNION
SELECT '>= 10'
UNION
SELECT '>= 20'
UNION
SELECT '>= 30'
) AS c
ON (`category` = '>= 30' AND (YEAR('2018-12-31') - YEAR(`dr`.`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`dr`.`StartDateTCDR`, '%m%d')) >= 30))
OR (`category` = '>= 20' AND (YEAR('2018-12-31') - YEAR(`dr`.`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`dr`.`StartDateTCDR`, '%m%d')) >= 20))
OR (`category` = '>= 10' AND (YEAR('2018-12-31') - YEAR(`dr`.`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`dr`.`StartDateTCDR`, '%m%d')) >= 10))
OR (`category` = '< 10' AND (YEAR('2018-12-31') - YEAR(`dr`.`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`dr`.`StartDateTCDR`, '%m%d')) < 10))
)
GROUP BY `ExistingPlanned`, `ResponsibleOrg`, `StartDateTCDR`, `EndDateTCDR`, `SpecificEndDate`, `ResponsibleOrgOut`, `StartDate`, `EndDate`, `ActualLength`, `TCDRLength`
ORDER BY `ResponsibleOrg` ASC, `RecordCount` DESC, `ResponsibleOrgOut` ASC, `ActualLength` DESC, `TCDRLength` DESC
LIMIT 0, 2000
Join your table with a subquery that returns all the categories, then check whether the row fits the category. Here's a simplification showing just that part of the query, I don't have time right now to fill in your entire query.
SELECT category, COUNT(*)
FROM ...
JOIN (
SELECT '< 10' AS category
UNION
SELECT '>= 10'
UNION
SELECT '>= 20'
UNION
SELECT '>= 30'
) AS c ON (category = '>= 30' AND (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 30))
OR (category = '>= 20' AND (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 20))
OR (category = '>= 10' AND (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) >= 10))
OR (category = '< 10' AND (YEAR('2018-12-31') - YEAR(`StartDateTCDR`) - (DATE_FORMAT('2018-12-31', '%m%d') < DATE_FORMAT(`StartDateTCDR`, '%m%d')) < 10))
GROUP BY Category, `ExistingPlanned`, `ResponsibleOrg`, `StartDateTCDR`, `EndDateTCDR`, `SpecificEndDate`, `ResponsibleOrgOut`, `StartDate`, `EndDate`, `ActualLength`, `TCDRLength`
Another way to do it would be a UNION
of 4 queries, which each test for the age in their WHERE
clauses.
In this case, the solution was not necessary to be done with a single query where the processing was done on SQL side. I opted for a broader query that got all the data at one shot, then processed the result set with PHP to get to the results I need.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.