How to sort by month in MySQL - mysql

Here is demo
The order is November and October. How can I add ORDER BY to this, so that the order is by month, Jan, Feb, Mar...etc.
Thanks in advance.
CREATE TABLE `hw_homework` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`studentid` int(10) NOT NULL,
`subjectid` int(10) NOT NULL,
`assignment_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`teacherid` int(10) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=55 ;
--
-- Dumping data for table `hw_homework`
--
INSERT INTO `hw_homework` (`id`, `studentid`, `subjectid`, `assignment_name`, `teacherid`, `date`) VALUES
(52, 56, 13, '1A', 20, '2012-10-28'),
(53, 56, 6, '12', 18, '2012-10-28'),
(54, 56, 4, 'page42', 59, '2012-11-02');
SELECT studentID,
DATE_FORMAT(`date`,'%M') `month`,
COUNT(studentid) totalMissed
FROM hw_homework
WHERE studentid = 56
GROUP BY studentid, DATE_FORMAT(`date`, '%M')

As Chuidiang suggested I added the following to get what I wanted.
Thanks everyone.
ORDER BY Month(date)

In your case it is ordering based on aplhabets.
Following will give correct result.
SELECT studentID,
DATE_FORMAT(`date`,'%M') `month`,
COUNT(studentid) totalMissed
FROM hw_homework
WHERE studentid = 56
GROUP BY studentid, DATE_FORMAT(`date`, '%M')
ORDER BY DATE_FORMAT(`date`,'%m')

Stumbled across this post trying to find the solution to sort by Month name. Probably not very elegant solution, but you can use the FIELD string function to get that result set.
SELECT
studentID,
DATE_FORMAT(`date`, '%M') `month`,
COUNT(studentid) totalMissed FROM
hw_homework WHERE
studentid = 56 GROUP BY
studentid,
DATE_FORMAT(`date`, '%M') ORDER BY
FIELD(
DATE_FORMAT(`date`, '%M'),
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
);
Try that. Also you can perhaps replace DATE_FORMAT with the easier function MONTHNAME(date) for readability purposes.

SELECT studentID,
DATE_FORMAT(`date`,'%M') as `month`,
COUNT(studentid) totalMissed
FROM hw_homework
WHERE studentid = 56
order by Month(month)
GROUP BY studentid, DATE_FORMAT(`date`, '%M')

SELECT studentID,
DATE_FORMAT(`date`,'%M') `month`,
COUNT(studentid) totalMissed
FROM hw_homework
WHERE studentid = 56
GROUP BY MONTH(DATE) ASC

Use as follows in your query
GROUP BY MONTH(date)

mysql> select * from hw_homework order by date asc; //increasing order
OR
mysql> select * from hw_homework order by date desc;

Related

How to get difference or delta of counts entries of each days with window functions?

I have a table with few fields like id, country, ip, created_at. Then I am trying to get the deltas between total entry of one day and total entry of the next day.
CREATE TABLE session (
id int NOT NULL AUTO_INCREMENT,
country varchar(50) NOT NULL,
ip varchar(255),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
INSERT INTO `session` (`id`, `country`, `ip`, `created_at`) VALUES
('1', 'IN', '10.100.102.11', '2021-04-05 20:26:02'),
('2', 'IN', '10.100.102.11', '2021-04-05 19:26:02'),
('3', 'US', '10.120.102.11', '2021-04-17 10:26:02'),
('4', 'US', '10.100.112.11', '2021-04-16 12:26:02'),
('5', 'AU', '10.100.102.122', '2021-04-12 19:36:02'),
('6', 'AU', '10.100.102.122', '2021-04-12 18:20:02'),
('7', 'AU', '10.100.102.122', '2021-04-12 23:26:02'),
('8', 'US', '10.100.102.2', '2021-04-16 21:33:01'),
('9', 'AU', '10.100.102.122', '2021-04-18 20:46:02'),
('10', 'AU', '10.100.102.111', '2021-04-04 13:19:12'),
('11', 'US', '10.100.112.11', '2021-04-16 12:26:02'),
('12', 'IN', '10.100.102.11', '2021-04-05 15:26:02'),
('13', 'IN', '10.100.102.11', '2021-04-05 19:26:02');
Now I have written this query to get the delta
SELECT T1.date1 as date, IFNULL(T1.cnt1-T2.cnt2, T1.cnt1) as delta from (
select TA.dateA as date1, MAX(TA.countA) as cnt1 from (
select DATE(created_at) AS dateA, COUNT(*) AS countA
FROM session
GROUP BY DATE(created_at)
UNION
select DISTINCT DATE(DATE(created_at)+1) AS dateA, 0 AS countA
FROM session
) as TA
group by TA.dateA
) as T1
LEFT OUTER JOIN (
select DATE(DATE(created_at)+1) AS date2,
COUNT(*) AS cnt2
FROM session
GROUP BY DATE(created_at)
) as T2
ON T1.date1=T2.date2
ORDER BY date;
http://sqlfiddle.com/#!9/4f5fd26/60
Then I am getting the results as
date delta
2021-04-04 1
2021-04-05 3
2021-04-06 -4
2021-04-12 3
2021-04-13 -3
2021-04-16 3
2021-04-17 -2
2021-04-18 0
2021-04-19 -1
Now, is there any place of improvements/optimizes on it with/or window functions? (I am zero with SQL, still playing around).
Try a shorter version
with grp as (
SELECT t.dateA, SUM(t.cnt) AS countA
FROM session,
LATERAL (
select DATE(created_at) AS dateA, 1 as cnt
union all
select DATE(DATE(created_at)+1), 0 as cnt
) t
GROUP BY dateA
)
select t1.dateA as date, IFNULL(t1.countA-t2.countA, t1.countA) as delta
from grp t1
left join grp t2 on DATE(t2.dateA + 1) = t1.dateA
order by t1.dateA
db<>fiddle

Mysql select from one table

My Table structure is
id;product_id;sell_type;sell_state
sell_type: BUY, SELL
sell_state: OPEN, FILLED, CANCELED
How to select only product_id with each 2 operation, BUY & SELL in sell_type and FILLED in sell_state
CREATE TABLE `orderlist` (
`id` int(10) UNSIGNED NOT NULL,
`product_id` int(11) NOT NULL,
`sell_type` enum('BUY','SELL') DEFAULT NULL,
`sell_state` enum('OPEN','FILLED','CANCELED') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `orderlist` (`id`, `product_id`, `sell_type`, `sell_state`) VALUES
(7, 1, 'BUY', 'FILLED'),
(8, 1, 'SELL', 'FILLED'),
(9, 2, 'BUY', 'FILLED'),
(10, 3, 'SELL', 'FILLED');
You could use a group by and count(distinct sell_state) = 2
select product_id
from orderlist
where sell_state ='FILLED'
and sell_type in ('BUY', 'SELL')
group by product_id
having count(distinct sell_type) = 2
http://sqlfiddle.com/#!9/c41301/2
try this select query
SELECT t1.*
FROM temp t1
INNER JOIN temp t2
ON t1.product_id = t2.product_id AND FIND_IN_SET('FILLED',t1.sell_state) > 0
WHERE FIND_IN_SET('BUY',t1.sell_type) > 0 AND
CONCAT(",", t2.sell_type, ",") REGEXP ",(BUY|SELL),"
GROUP BY t1.product_id
demo : http://sqlfiddle.com/#!9/7fcd9/64
try this
SELECT product_id
FROM orderlist
WHERE sell_state = 'FILLED' AND sell_type IN ('BUY','SELL')
GROUP BY product_id
HAVING COUNT(product_id) > 2
demo: http://sqlfiddle.com/#!9/464959/2

mySQL - return 0 as an aggregate result if a field not found

If for example I have:
CREATE TABLE application (
`id` INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`month` VARCHAR(255) NOT NULL,
`amount` DECIMAL(9,2) NOT NULL)
;
INSERT INTO application
(`id`, `month`, `amount`)
VALUES
(1, 'january', 2000.00),
(2, 'february', 1000.00),
(3, 'january', 3000.00),
(4, 'january', 5000.00)
;
And then I run the query:
SELECT SUM(`amount`) as sum FROM application WHERE month IN ('january', 'february', 'march') GROUP BY `month`;
I get the result:
month sum
___________________
january | 10000.00
february | 1000.00
which is what the query was supposed to do however I'm looking for this result:
month sum
___________________
january | 10000.00
february | 1000.00
march | 0.00
how can I achieve this?
if anyone needs clarity don't vote down just ask and I will be more precise if i can.
cheers
SELECT m.mname, SUM(ISNULL(a.`amount`,0)) as sum
FROM
(
select 'january' as mname union all
select 'february' as mname union all
select 'march' as mname
) m LEFT JOIN application a on a.`month` = m.mname
GROUP BY a.`month`

How to find the latest week and month from MySQL

This DEMO shows by month. And this DEMO shows by week. However I want to display
Q1: only this week of each student.
Q2: only this month of each student.
Q3: only last week of each student.
Q4: only last month of each student.
How can I achieve this?
CREATE TABLE `hw_homework` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`studentid` int(10) NOT NULL,
`subjectid` int(10) NOT NULL,
`assignment_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`teacherid` int(10) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ;
INSERT INTO `hw_homework` (`id`, `studentid`, `subjectid`, `assignment_name`, `teacherid`, `date`) VALUES
(1, 29, 5, '5E', 20, '2012-10-31 13:58:40'),
(2, 15, 5, '32B', 20, '2012-10-31 13:59:54'),
(3, 29, 4, 'Q2A', 20, '2012-10-30 17:53:46'),
(4, 29, 11, '6E', 20, '2012-10-02 20:06:39'),
(5, 29, 11, 'C15', 20, '2012-10-16 20:06:30'),
(6, 15, 11, '7A', 20, '2012-09-19 20:08:05'),
(7, 29, 5, '3B', 20, '2012-09-14 20:08:12'),
(8, 29, 13, '6E', 32, '2012-10-29 20:23:46'),
(9, 29, 11, '7E', 18, '2012-10-30 14:35:14'),
(10, 2, 5, '5E', 20, '2012-10-21 13:58:40'),
(11, 2, 5, '5E', 20, '2012-10-30 13:58:40'),
(12, 2, 5, '5E', 20, '2012-10-31 13:58:40');
By month
SELECT studentID,
DATE_FORMAT(`date`, '%M') `month`,
COUNT(studentID) totalMissed
FROM hw_homework
-- WHERE studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%M')
By week
SELECT studentID,
DATE_FORMAT(`date`, '%U') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework
-- WHERE studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%U')
Thanks in advance.
A1 :
SELECT studentID,
DATE_FORMAT(`date`, '%U') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework
WHERE DATE_FORMAT(`date`, '%U') = DATE_FORMAT(NOW(), '%U')
-- AND studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%U')
A2 :
SELECT studentID,
DATE_FORMAT(`date`, '%M') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework
WHERE DATE_FORMAT(`date`, '%M') = DATE_FORMAT(NOW(), '%M')
-- AND studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%M')
A3 :
SELECT studentID,
DATE_FORMAT(`date`, '%U') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework he
WHERE DATE_FORMAT(`date`, '%U') = (SELECT MAX(DATE_FORMAT(NOW(), '%U')) FROM hw_homework hi WHERE hi.studentID = he.studentID)
-- AND studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%U')
A4 :
SELECT studentID,
DATE_FORMAT(`date`, '%M') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework he
WHERE DATE_FORMAT(`date`, '%M') = (SELECT MAX(DATE_FORMAT(NOW(), '%M')) FROM hw_homework hi WHERE hi.studentID = he.studentID)
-- AND studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%M')

How to find data from last week in MySQL

I want to display data from
Q1: only last week of each student.
Q2: only last month of each student.
How can I achieve this?
DEMO for week
DEMO for month
CREATE TABLE `hw_homework` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`studentid` int(10) NOT NULL,
`subjectid` int(10) NOT NULL,
`assignment_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`teacherid` int(10) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ;
INSERT INTO `hw_homework` (`id`, `studentid`, `subjectid`, `assignment_name`, `teacherid`,
`date`) VALUES
(1, 29, 5, '5E', 20, '2012-11-04 13:58:40'),
(2, 15, 5, '32B', 20, '2012-11-04 13:59:54'),
(3, 29, 4, 'Q2A', 20, '2012-10-30 17:53:46'),
(4, 29, 11, '6E', 20, '2012-11-02 20:06:39'),
(5, 29, 11, 'C15', 20, '2012-10-16 20:06:30'),
(6, 15, 11, '7A', 20, '2012-09-19 20:08:05'),
(7, 29, 5, '3B', 20, '2012-09-14 20:08:12'),
(8, 29, 13, '6E', 32, '2012-10-29 20:23:46'),
(9, 29, 11, '7E', 18, '2012-10-30 14:35:14'),
(10, 2, 5, '5E', 20, '2012-10-21 13:58:40'),
(11, 2, 5, '5E', 20, '2012-10-30 13:58:40'),
(12, 2, 5, '5E', 20, '2012-10-31 13:58:40');
This does not work for last week. It shows this week result.
SELECT studentID,
DATE_FORMAT(`date`, '%U') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework he
WHERE DATE_FORMAT(`date`, '%U') = (SELECT MAX(DATE_FORMAT(NOW(), '%U')) FROM hw_homework hi WHERE hi.studentID = he.studentID)
-- AND studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%U')
This does not work for last month. This shows this month result.
SELECT studentID,
DATE_FORMAT(`date`, '%M') `Month`,
COUNT(studentID) totalMissed
FROM hw_homework he
WHERE DATE_FORMAT(`date`, '%M') = (SELECT MAX(DATE_FORMAT(NOW(), '%M')) FROM hw_homework hi WHERE hi.studentID = he.studentID)
-- AND studentID = ''
GROUP BY studentID, DATE_FORMAT(`date`, '%M')
Thanks in advance.
try subtracting 1 from weekNo:
SELECT studentID,
DATE_FORMAT(`date`, '%U') `WeekNo`,
COUNT(studentID) totalMissed
FROM hw_homework he
WHERE DATE_FORMAT(`date`, '%U') =
(SELECT MAX(DATE_FORMAT(NOW(), '%U')-1)
FROM hw_homework hi
WHERE hi.studentID = he.studentID)
GROUP BY studentID, DATE_FORMAT(`date`, '%U')