This question already has answers here:
MySQL 5.6 - DENSE_RANK like functionality without Order By
(3 answers)
Closed 15 days ago.
I am using DENSE_RANK() for alloting rank, but my MYSQL version is 5.7 that does not support DENSE_RANK()
DENSE_RANK() OVER (ORDER BY (IFNULL((SUM(CASE WHEN DATEDIFF(lt.dispatch_date,t.received_at)<=2 OR DATEDIFF(t.received_at,t.created_at) <= 2 THEN 1 ELSE 0 END)
/(SUM(CASE WHEN DATEDIFF(lt.dispatch_date,t.received_at)<=2 OR DATEDIFF(t.received_at,t.created_at) <= 2 THEN 1 ELSE 0 END)
+SUM(CASE WHEN DATEDIFF(lt.dispatch_date,t.received_at)>2 OR DATEDIFF(t.received_at,t.created_at) > 2 THEN 1 ELSE 0 END)))
*100,0)+(IFNULL((IFNULL(SUM(DATEDIFF(d.created_at,t.received_at) <= 2),0)/(IFNULL(SUM(DATEDIFF(d.created_at,t.received_at) <= 2),0)+
IFNULL(SUM(DATEDIFF(d.created_at,t.received_at) > 2),0))),0)*100))/2 DESC) dens_rank
expecting
Your observation is correct. You need to upgrade to MySQL 8 if you want to use DENSE_RANK()
Related
Is there a better way of using SQL (mysql) to aggregate by 6 month windows? This seems to perform okay gets the relevant data in the normal case, but is obviously limited.
SELECT SUM(...) some_aggg,
(CASE
WHEN SOME_DATE > DATE_SUB(now(), INTERVAL 6 MONTH) THEN 3
WHEN SOME_DATE > DATE_SUB(now(), INTERVAL 12 MONTH) THEN 2
WHEN SOME_DATE > DATE_SUB(now(), INTERVAL 18 MONTH) THEN 1
ELSE 0
END) RECENCY
WHERE ...
GROUP BY RECENCY
ORDER BY RECENCY DESC
How about a little arithmetics?
select sum(...) some_aggg,
floor(timestampdiff(month, some_date, now()) / 6) recency
where ...
group by recency
order by recency
recency gives you an integer value that starts at 0 (the date is less than 6 months old) and increments by 1 for every 6 month period: 1 means between 6 months and 1 year old, and so on.
I am trying to write a query that counts the number of records that were created every 7 days,
Using this query i get the number of records created per day,
SELECT 'Closed' AS `Status`, COUNT(*) AS `Count`, `raisedon` AS `Date` FROM table WHERE raisedon >= '2019-01-01' and raisedon < '2019-03-29' AND status = 'Open' AND type = 'A' AND location = 'B' AND locationid = 'C' GROUP BY raisedon
This returns
Closed 1 2019-01-01
Closed 1 2019-01-14
Closed 2 2019-01-16
Closed 1 2019-01-24
Closed 1 2019-01-25
Closed 1 2019-01-30
Closed 1 2019-02-01
Closed 1 2019-02-03
Closed 1 2019-02-28
Closed 1 2019-03-07
Closed 1 2019-03-08
I would like the results to be like
Closed 1 2019-01-01
Closed 1 2019-01-08
Closed 2 2019-01-15
Closed 2 2019-01-22
Closed 3 2019-01-29
Closed 0 2019-02-05
Closed 0 2019-02-12
Closed 0 2019-02-19
Closed 1 2019-02-26
Closed 2 2019-03-05
Is this possible with just a query or will i have to use javascript aswell,
I am using phpmyadmin with mysql
Thanks for any advice
If you are not too picky about your edge conditions for where a given week starts, you might just be able to aggregate using YEARWEEK:
SELECT
'Closed' AS Status,
COUNT(*) AS cnt,
YEARWEEK(raisedon) AS week
FROM yourTable
WHERE
raisedon >= '2019-01-01' AND raisedon < '2019-03-29' AND
status = 'Open' AND
type = 'A' AND
location = 'B' AND
locationid = 'C'
GROUP BY
YEARWEEK(raisedon);
This answer assumes that your data would have at least one data point present for each week. If there could be large gaps, then one solution would be to join with a calendar table. Here is an example of how to do this:
SELECT
'Closed' AS Status,
COUNT(t2.raisedon) AS cnt,
YEARWEEK(t1.raisedon) AS week
FROM
(
SELECT '2019-01-01' AS raisedon UNION ALL
SELECT '2019-01-02' UNION ALL
SELECT '2019-01-03' UNION ALL
...
SELECT '2019-01-31' UNION ALL
SELECT '2019-02-01' UNION ALL
...
SELECT '2019-03-31'
) t1
LEFT JOIN yourTable t2
ON t1.raisedon = t2.raisedon
WHERE
t1.raisedon >= '2019-01-01' AND t1.raisedon < '2019-03-29' AND
t2.status = 'Open' AND
t2.type = 'A' AND
t2.location = 'B' AND
t2.locationid = 'C'
GROUP BY
YEARWEEK(t1.raisedon);
See here for several ways to generate a calendar table like the one used above in the second query.
One method uses datediff():
SELECT 'Closed' AS `Status`,
COUNT(*) AS `Count`,
MIN(raisedon) AS `Date`
FROM table
WHERE raisedon >= '2019-01-01' AND
raisedon < '2019-03-29' AND
status = 'Open' AND
type = 'A' AND
location = 'B' AND
locationid = 'C'
GROUP BY FLOOR(DATEDIFF('2019-01-01', raisedon) / 7);
This question already has answers here:
generate_series() equivalent in MySQL
(4 answers)
Closed 5 years ago.
Can anyone fluent in both MySQL and PostgreSQL translate this to MySQL?
SELECT *
FROM generate_series(DATE_TRUNC('day', NOW() - interval '30 day'),
DATE_TRUNC('day', NOW()),
interval '1 day'
)
I know that generate_series() does not exist in MySQL. Is there a similar function?
There is no equivalent. MySQL doesn't have CTEs, generate_series(), or even window functions.
If you have a table that is big enough (in this case 31 rows), you can do:
select (curdate() - interval (#rn := #rn + 1) day) as dte
from t cross join
(select #rn := -1)
limit 31;
Maybe there is a simple fix but I can't seam to figure it out. I'll try my best to explain my situation.
I'm working on a MySQL query that will return results within date range (in column A), and for date range - 1 year (in column B). I need to group results by month day and not by year. So I would like to have something like this:
2014 2013
----------------
01-01 6 8
01-03 7 0
01-04 4 1
01-08 0 13
01-21 11 7
In my current query (below) I get results like this (because of ELSE in CASE):
2014 2013
----------------
01-01 0 8
01-03 7 0
01-04 0 1
01-08 0 13
01-21 0 7
QUERY:
SELECT
DATE_FORMAT(table.date, '%e.%c.') AS date,
(CASE WHEN DATE(table.date) BETWEEN '2014-01-01' AND '2014-02-01' THEN ROUND(SUM(table.field), 2) ELSE 0 END) AS field_2014,
(CASE WHEN DATE(table.date) BETWEEN '2013-01-01' AND '2013-02-01' THEN ROUND(SUM(table.field), 2) ELSE 0 END) AS field_2013
FROM table
WHERE
(DATE(table.date) BETWEEN '2014-05-01' AND '2014-06-01' OR DATE(table.date) BETWEEN '2013-05-01' AND '2013-06-01')
GROUP BY
DATE_FORMAT(table.date, '%c.%e.')
What should I put in ELSE and how can I achieve this functionality?
Thank you for your time
You need aggregation functions. I would recommend:
SELECT DATE_FORMAT(t.date, '%e.%c.') AS date,
SUM(CASE WHEN year(t.date) = 2014 THEN ROUND(SUM(t.field), 2) ELSE 0 END) AS field_2014,
SUM(CASE WHEN year(t.date) = 2013 THEN ROUND(SUM(t.field), 2) ELSE 0 END) AS field_2013
FROM table t
WHERE year(t.date) in (2013, 2014) and month(t.date) = 5
GROUP BY DATE_FORMAT(t.date, '%c.%e.');
I would also recommend using the format '%m-%d'. Having the month then the year means that order by will work on the column. Having all the dates be the same width ("05/01" rather than "5/1") better corresponds to your desired output.
This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 9 years ago.
I have got some result for this query but instead of it i want to change a result like below
Result to be shown::
2011 2012
26267.620000000003 404603.20999999996
144384.36 173245.96000000002
199704.47999999998 208524.42
Query
SELECT
YEAR (PAYMENTDATE) AS YEARNUMBER,
MONTH (PAYMENTDATE) AS MONNUMBER,
SUM (AMOUNT) AS MONTOTAL
FROM
PAYMENTS
GROUP BY
YEAR (PAYMENTDATE)
Result:: for above query
2011 26267.620000000003
2011 144384.36
2012 173245.96000000002
2012 208524.42
Try this:
SELECT MONNUMBER,
MAX(CASE WHEN YEARNUMBER = 2011 THEN MONTOTAL ELSE 0 END) AS Year2011,
MAX(CASE WHEN YEARNUMBER = 2012 THEN MONTOTAL ELSE 0 END) AS Year2011
FROM (SELECT YEAR(PAYMENTDATE) AS YEARNUMBER, MONTH(PAYMENTDATE) AS MONNUMBER,
SUM(AMOUNT) AS MONTOTAL
FROM PAYMENTS
GROUP BY YEAR(PAYMENTDATE)
) AS A
GROUP BY MONNUMBER