Experts ,
What is best way to get last 13 months name inducing current month. In the table I have records for every month from 2014.
Note : date format is - 2016-01-15 , each month has multiple records in table.
something like below
SELECT MONTHNAME(start_date) as month_name
FROM purchase_order_entry_reports
WHERE start_date (needs to select last 13 months )
Result i'm looking for
November,
December,
January,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November
SELECT distinct YEAR(start_date), MONTHNAME(start_date) as month_name
FROM purchase_order_entry_reports
WHERE start_date BETWEEN now() - interval 13 month
AND now()
Related
I have a table wherein I want to get the total prices of a column in specific dates. The dates are strings (eg: January 2018). What I have tried is to convert the string to date.
SELECT
SUM(price_amount) as 'total_paid',
STR_TO_DATE(CONCAT('01 ',price_month), "%M %d %Y") as dates
FROM user_prices
WHERE price_type = 'cash' AND price_month >= DATE('January 01 2018')
GROUP BY price_month
ORDER BY price_month DESC;
The result of this is null. I have to get only the sum of each existing month in the table that dates are equal or greater January 01 2018. And also group them by month.
email price_amount price_month price_type date_added
1#gmail.com 200 April 2017 cash ---
19#gmail.com 400 December 2017 cash ---
12#gmail.com 100 January 2018 cash ---
123#gmail.com 230 January 2018 cash ---
1234#gmail.com 250 January 2018 credit ---
321#gmail.com 200 April 2018 cash ---
32#gmail.com 120 March 2018 cash ---
So the example above should show the expected result below:
price_month total_paid
March 2018 120
April 2018 200
January 2018 330
If the price_month column is actually literal text as you have shown us, then you'll need to use STR_TO_DATE to make this query work. Note that STR_TO_DATE requires at least year, month, and day information in order to generate a date. So, in the query below, I arbitrarily build each month year data as occurring on the first of the month.
SELECT
price_month,
SUM(price_amount) AS total_paid
FROM user_prices
WHERE
STR_TO_DATE(CONCAT('01 ', price_month), '%d %M %Y') >= '2018-01-01' AND
price_type = 'cash'
GROUP BY
price_month,
STR_TO_DATE(CONCAT('01 ', price_month), '%d %M %Y')
ORDER BY
STR_TO_DATE(CONCAT('01 ', price_month), '%d %M %Y');
Demo
Moving forward, please don't store your dates as text like this. In general, you may assume that a puppy gets run over every time you have to use STR_TO_DATE in a MySQL query.
In sorting the ORDER BY of dates in MySQL, I'm trying to sort ASC for dates after today, and DESC for dates before today in one go.
I'm doing something similar to:
SELECT * FROM test ORDER BY IF(created >= NOW(), created, 1) ASC, created DESC
This gives me a somewhat desired result:
ID CREATED
8 May, 10 2014 11:15:00+0000
7 May, 03 2014 20:47:00+0000
5 May, 02 2014 14:00:00+0000
4 April, 30 2014 17:41:00+0000
3 April, 30 2014 17:00:00+0000
1 April, 21 2014 03:30:00+0000
6 March, 23 2014 12:00:00+0000
9 May, 20 2014 20:45:00+0000
10 July, 02 2014 20:30:00+0000
2 June, 30 2015 11:16:00+0000
Before today is DESC, after today is ASC. However, I want to see the block of ID's 9,10,2 at the top of the results.
Any thoughts on how to do this is appreciated.
Test Link: http://www.sqlfiddle.com/#!2/4667b/2/0
Add an additional condition to the order by, which is a binary indicator of whether the date is in the past or future:
SELECT *
FROM test
ORDER BY (created >= NOW()) desc,
IF(created >= NOW(), created, NULL) ASC,
created DESC;
how about splitting it up into 2 sql queries and then unioning the results?
(SELECT * FROM test WHERE created >= NOW() ORDER BY created ASC)
UNION
(SELECT * FROM test WHERE created < NOW() ORDER BY created DESC)
Sorry to bother you again, i have difficulties in formulating my query . i have two columns with a date values. (see sample below)
Posting Date col B
Feb 02,2013 feb 01, 2013
Feb 02, 2013
feb 15, 2013
mar 03,2013 mar 01, 2013
april 12, 2013 april 12, 2013
if my parameter is a range of date based on col B (ex. where colB between 02/01/2013 and 02/28/2013).
I want to show all value in Posting date which is part of the date range i had filtered. say, having month of Feb and 2013 as year
results:
Posting Date col B
Feb 02,2013 feb 01, 2013
Feb 02, 2013
feb 15, 2013
Is this what you're looking for? Is your field type of your Posting_Date column a Date? If so, then this should work:
SELECT Posting_Date, ColB
FROM YourTable
WHERE Posting_Date >= '2013-02-01'
AND Posting_Date < '2013-03-01'
I prefer using >= and < rather than BETWEEN.
If your Posting_Date field is stored as a varchar, then use STR_TO_DATE:
SELECT Posting_Date, ColB
FROM YourTable
WHERE STR_TO_DATE(Posting_Date , '%M %d,%Y') >= '2013-02-01'
AND STR_TO_DATE(Posting_Date , '%M %d,%Y') < '2013-03-01'
SQL Fiddle Demo
There seem to be a weird behaviour when comparing a date in table column with a date generated in a list within MYSQL.
Please take a look at the * SQLFIDDLE reference.
Payroll Table:
ID DATESTAMP
1 August, 30 2012 00:00:00+0000
2 September, 02 2012 00:00:00+0000
3 September, 15 2012 00:00:00+0000
4 September, 24 2012 00:00:00+0000
5 October, 05 2012 00:00:00+0000
6 October, 16 2012 00:00:00+0000
7 October, 19 2012 00:00:00+0000
8 November, 02 2012 00:00:00+0000
9 November, 10 2012 00:00:00+0000
10 November, 16 2012 00:00:00+0000
11 November, 24 2012 00:00:00+0000
12 November, 30 2012 00:00:00+0000
13 December, 01 2012 00:00:00+0000
14 December, 07 2012 00:00:00+0000
Dates list is generated between two particular dates with a constant day interval
Query:
set #i:= 0;
SELECT date_format(DATE(ADDDATE('2012-10-05',
INTERVAL #i:=#i+14 DAY)),'%Y-%m-%d')
AS dateP, #i
FROM payroll
HAVING #i < datediff(now(), date '2012-10-05')
;
DATEP #IntervalDays
2012-10-19 14
2012-11-02 28
2012-11-16 42
2012-11-30 56
2012-12-14 70
As you can see the generated dates list has matches to the Payroll table above. However when the comparison is done, it reutns zero records.
Comparison Query:
set #i:= 0;
SELECT distinct datestamp FROM payroll
WHERE date(datestamp) in (
SELECT DATE(ADDDATE('2012-10-05',
INTERVAL #i:=#i+14 DAY) ) AS dateP
FROM payroll
where #i < DATEDIFF(now(), date '2012-10-05')
)
;
So Questions I have:
Is the inner query stop generating dates when used as a nested query?
Is there anything wrong with the dates comparison method I am using here?
What could be the reason for this entire failure?
How to fix it within Select itself without any procedure/functions? :)
PS:
I am also trying to test this in SQL server as well as Oracle.
There are many good questions and answers to support 'Date Comparison' issues occurred at various scenarios with the site. That includes posts such as mysql date comparison with date_format. etc.. May be there's one hidden somewhere asking for exact issue I am facing with different wording. Couldn't find and hence posted the question.
Second UPDATE:
Now I got it working in every version:
select
*
from
Payroll
inner join
(
SELECT DATE(DATE_ADD('2012-10-05',
INTERVAL #i:=#i+14 DAY) ) AS dateP
FROM Payroll, (SELECT #i:=0) r
where #i < DATEDIFF(now(), date '2012-10-05')
) sq on Payroll.datestamp = sq.dateP
You just have to initialize the variable inside the query.
UPDATE:
Strange thing is, this one works on my local machine without problems (version 5.1.41-3ubuntu12.7-log), but not in your SQLfiddle.
set #i:= 0;
select
*
from
Payroll
inner join
(
SELECT DATE(DATE_ADD('2012-10-05',
INTERVAL #i:=#i+14 DAY) ) AS dateP
FROM Payroll
where #i < DATEDIFF(now(), date '2012-10-05')
) sq on Payroll.datestamp = sq.dateP
END OF UPDATE
Have you tried it like this?
set #i:= 0;
SELECT distinct datestamp FROM payroll
WHERE STR_TO_DATE(datestamp, '%M, %d %Y %H:%i:%f') in (
SELECT DATE(ADDDATE('2012-10-05',
INTERVAL #i:=#i+14 DAY) ) AS dateP
FROM payroll
where #i < DATEDIFF(now(), date '2012-10-05')
)
;
My guess is, that the DATE() function fails, cause you're varchar(is it?) date is not in ISO format. Therefore you have to use STR_TO_DATE() function.
For exact usage of STR_TO_DATE() read here and here. I'm not sure about the microsecond part.
I have the following table (simplified):
user_id date hours
1 2012-03-01 5
2 2012-03-01 8
3 2012-03-01 6
1 2012-03-02 3
3 2012-03-02 7
What I want is to get the the sum of hours worked for a given user id (ex. 1), and the total hours worked regardless of what user (for a given time period) in a single query.
So for user_id = 1, and time period: 2012-03-01 - 2012-03-02 the query should return: own=8, total=29.
I can do it in two separate queries, but not in a single one.
Use CASE:
SELECT SUM(
CASE user_id
WHEN 1 THEN hours
ELSE 0
END) as Own,
SUM(hours) as Total
FROM HoursWorked
WHERE date BETWEEN '2012-03-01' AND '2012-03-02';
I think I have something that works using the following schema:
CREATE TABLE hoursWorked
(
id int,
date date,
hours int
);
INSERT INTO hoursWorked
(id, date, hours)
VALUES
('1','2012-03-01','5'),
('2','2012-03-01','8'),
('3','2012-03-01','6'),
('1','2012-03-02','3'),
('3','2012-03-02','7');
And this query:
select parent.id, parent.date, parent.hours, (select sum(hours)
from hoursWorked child
where child.id = parent.id) as totalHours
from hoursWorked parent
I was able to get these results:
ID DATE HOURS TOTALHOURS
1 March, 01 2012 00:00:00-0800 5 8
2 March, 01 2012 00:00:00-0800 8 8
3 March, 01 2012 00:00:00-0800 6 13
1 March, 02 2012 00:00:00-0800 3 8
3 March, 02 2012 00:00:00-0800 7 13
Diego's answer albeit procedural is a great way to get the answer you are looking for. Of course for your date range you would need to add a WHERE date BETWEEN 'startdate' AND 'enddate'. The dates need to be in a format that mysql recognizes, typically 'yyyy-mm-dd'
Another solution that doesn't get you the results in one row, but in a result set would be to do a UNION
SELECT user_id, SUM(hours) as hours FROM table WHERE date BETWEEN 'startdate' AND 'enddate' WHERE user_id = 3
UNION
SELECT null as user_id, SUM(hours) as hours FROM table WHERE date BETWEEN 'startdate' AND 'enddate'