My SQL - creating a grouped date list from database dates - mysql

I have a view that list available dates from an online calendar (basically, I created entries for all available dates and then compare this to the dates that have been booked out - the view then show all dates within 'AvailableDates' where 'Date' <> 'BookedDate'.
So far I can get it to run a list that looks like this....
24th January 2014
7th February 2014
8th February 2014
....but this takes up a lot of space and the idea is that the list can be copied and pasted into an email/message for quick reference.
What I'm looking for is a way to group the dates so that the output looks like this...
Jan - 24th
Feb - 7th, 8th
...so that there is a maximum of 12 lines.
Could somebody tell me how to do this? - the field is a 'date' type.
Thanks,
Darren

You might want to have the year in there, too, or you might get false results.
SELECT
YEAR(your_column) AS the_year,
DATE_FORMAT(your_column, '%b') AS the_month_abbreviated,
GROUP_CONCAT(DATE_FORMAT(your_column, '%D') ORDER BY DAY(your_column) SEPARATOR ', ') AS the_days
FROM your_table
GROUP BY YEAR(your_column), DATE_FORMAT(your_column, '%b')
ORDER BY YEAR(your_column), MONTH(your_column)
you can read more about the DATE_FORMAT() function here.
see it working live in an sqlfiddle

SELECT
MONTH(`d`),
GROUP_CONCAT(DAY(`d`))
FROM
a
GROUP BY
YEAR(`d`),
MONTH(`d`)
SQLFiddle

You have to convert the datecolumn to month and use GROUP_CONCAT(). Maybe this can work or at least in the right direction.
SELECT
LEFT(monthname(datecolumn),3),GROUP_CONCAT(DAY(datecolumn))
FROM table
GROUP BY CONCAT(YEAR(datecolumn),MONTH(datecolumn))
Missed to format the DAY. Now fixed

Related

Mysql query that finds dates for the previous month from meta_value

I have created a view called acquity_fields with 4 columns (see also view from phpMyAdmin attached):
meta_id; post_id; meta_key; meta_value
I was using this post Construct MySQL query ( meta_key/meta_value table) to help me to create a query so that I can pull the last month (e.g Sept 1-30 inclusive) as well as August for number of clients.
But I need to walk first so I wanted to display all months with number of clients in each then add in the additional statements for last month and previous.
Here is the query I put together for getting all the months and clients,
SELECT COUNT(*) as Clients, MONTHNAME(FROM_UNIXTIME(meta_key = 'wpcf-acquity-date')) as Month
FROM acquity_fields
WHERE (meta_key = 'wpcf-acquity-date')
GROUP BY Month
but it seems to be putting all the clients into one month and displaying it as:
Clients | Month
----------------------
399 | January
I am not sure if its the time conversion, but I am stumped to what is causing this. Any help would be great and thanks in advance!
View acquity_fields in phpmyadmin
In your select part of the query, FROM_UNIXTIME() takes in a timestamp, so try this:
SELECT COUNT(*) as Clients, MONTHNAME(FROM_UNIXTIME(meta_value)) as Month
FROM acquity_fields
WHERE (meta_key = 'wpcf-acquity-date')
GROUP BY Month
(meta_key = 'wpcf-acquity-date') is a WHERE condition, not a timestamp integer. If you have something that's not a timestamp, the system will treat it as a default date, and the output will become December or January depending on your settings.

Mysql in-time query

I'm in need of some help structuring in-time queries. There's a few of them I need - but I think that if I can be shown how to do one, I can figure out the others.
What I'm after:
-Rolling 12 month view of 'inactive accounts'...ie number of accounts that have not placed an order in the 12 months prior.
-This ideally will be a subquery (in a much larger script) joining back on to a dates table (see below)
January 2015 | # of customers with no orders from 1/2014-1/2015
February 2015 | # of customers with no orders from 2/2014-2/2015
March 2015 | # of customers with no orders from 3/2014-3/2015
etc...
What I'm having trouble wrapping my mind around is how I'd structure a where clause to ensure that it scans all orders and only returns the total of account ID's that had not placed an order in the year prior to that month. I've used different combinations of DATEDIFF, DATESUB etc.
SELECT DATE_FORMAT(order_datetime, '%Y-%m'), COUNT DISTINCT (account_id)
FROM warehouse.orders
JOIN warehouse.accounts ON xyz
WHERE...
It feels like I'm on the right path - I just keep mentally going in circles trying to figure this out.
Cheers and thanks in advance.
I don't have enough reputation points to simply comment on your question. I don't fully understand it though.
Are you using SQLServer/TSQL or MySQL?
Do you want to have just one column which calculates the last 12 months' rolling average or 12 columns for the rolling average each month? If it is just one figures for the last 12 months tolling do you want that to be from the current day or the beginning of that month?
If it was SQL Server and a rolling 12 months to now, the calculation could be:
SELECT SUM(CASE WHEN DATEDIFF(y,GETDATE(),order_date_time) < 1 THEN COUNT(DISTINCT account_id) END) as January2015
If you're using MySQL replace GETDATE() with NOW()
If you want one value rolling but to the beginning of the month then you could use:
SELECT SUM(CASE WHEN DATEDIFF(y,DATEADD(M, DATEDIFF(M, 0, GETDATE()), 0),order_date_time) < 1 THEN COUNT(DISTINCT account_id) END) as January2015
If I've missed the point entirely, please let me know and I'll happily amend the answer
You should query between dates, in order to get the count of events for each id.
select case
when count(account_id)<0 then 'INACTIVE'
when count(account_id)>0 then 'ACTIVE'
from warehouse.orders
where data_format(order_datetime, '%m/%Y') between '1/2014' and '1/2015'
group by account_id)

Retrieving Dates in MySql regardless of Years

I have dates stored in my MySQL database . (ex.: 1992-12-12 , 1983-01-02 , 1983-01-05 , 1983-01-10 )
I want to compare these dates only on Date & Month basis regardless of the years .
Also, i want to retrieve records having date between 2nd January and 5th January , whatever the Year be.
How do i do this?
Please help with the MySQL query.
This request should do what you are looking for. But this will not work perfectly after february because of the 29th
SELECT date
FROM ...
WHERE DAYOFYEAR(date) BETWEEN DAYOFYEAR('2011-01-02') AND DAYOFYEAR('2011-01-05');
First create a function to extract only the day and month part of the date(I have written to the best of my knowledge, there may be a more optimized way than this):
CREATE FUNCTION daymonth (date DATE)
RETURNS DATE
RETURN STR_TO_DATE(CONCAT(CONCAT((EXTRACT(MONTH FROM date)),'-'),(EXTRACT(DAY FROM date))),'%m-%d');
Then call the function in your query:
SELECT date
FROM ...
WHERE daymonth(date) BETWEEN daymonth('2011-01-02') AND daymonth('2011-01-05');
I would love to further discuss on this issue. :)
-Sandip

Order by date (varchar)?

I want to order by date.
e.g.
table_date
February 2011
January 2011
December 2010
I've already tried:
SELECT distinct(table_date) FROM tables ORDER BY table_date DESC
bur it doesn't work.
I get this instead:
January 2011
February 2011
December 2010
Can you help me please?
If you must store the dates in a varchar which as others pointed out is not recommended, you could use:
SELECT table_date FROM tables ORDER BY STR_TO_DATE(table_date, '%M %Y') DESC;
If you want to order by date, store it as a date, not a string. Unless your date string is of the form yyyy-mm-dd, it will not sort as you want it.
Databases are hard enough work as-is, without people making it harder, and you should be striving as much as possible to avoid what I like to call SQL gymnastics.
Store it as a date then, if you must, use date functions to get it in the form February 2011.
It'll be a lot easier going that way than what you're trying to do.
Even if you can't change any of the current columns due to code restrictions, you can always add another column to the database like TABLE_DATE_AS_DATE and put in an insert/update trigger to populate it based on TABLE-DATE.
Then just do:
update table x set table_date = table_date
or something similar, to fire the trigger for all rows.
Then, your query can still get at table_date but use table_date_as_date for ordering. That's a kludge of course but I've had to use tricks like that in the past when it was imperative the code could not change, so we had to resort to DBMS trickery.
Store dates as DATE, not as VARCHAR, that's a huge mistake. Use STR_TO_DATE() to convert your content. When you're done, you can order by dates without any problems.
Date should be stored as date and not VARCHAR.
Suppose you have table_date in the following format (DD-MM-YYYY)
table_date
2011-01-01
2011-02-01
2010-12-01
Now you can perform order by clause in the following way
SELECT * FROM table_order ORDER BY str_to_date(date, "%Y-%M-%D") ASC
I doubt if the output will be in ordered form

Query by month from date field

I have a set of Access d/b's grouped already by year. within a given year, I have a field caleld REPORTDATE which is a standard mm/dd/yyyy field. However, I need to produce queries that return data by the month. For example, I just want to see records for Jan, recs for Feb, Recs for March, etc., so that I can sum them and work wwith thm.
Do I use an expression in the query design view Criteria field?
Thanks in advance.
I just want to see records for Jan, recs for Feb, Recs for March, etc., so that I can sum them and work wwith thm.
You can do all of that in one sql statement:
select month(reportdate), sum( the column you wish to sum )
from tablename
group by month(reportdate);
BUT WAIT THERE'S MORE!
Further say that there are several salepersons selling stuff, and you wish to show each salesperson's sales by month
select month(reportdate), salesperson, sum( the column you wish to sum )
from tablename
group by month(reportdate), salesperson;
That shows the sum per month per salesperson.
You know the Germans always make good stuff!
What it you wanted to see the same sums, but rtaher than comparing salespeople against each other in each month, you wanted to compare, for each salesperson, how they did from one month to another?
Just reverse the order of the group by:
select month(reportdate), saleperson, sum( the column you wish to sum )
from tablename
group by salesperson, month(reportdate);
Tacos, Fettuccini, Linguini, Martini, Bikini, you're gonna love my nuts!
The power of SQL! As seen on TV! Order now!
"select month(reportdate), sum( the column you wish to sum )from tablenamegroup by month(reportdate);" THIS IS VERY HELPFUL, THANK YOU. AND YOU ARE HILARIOUS. HOWEVER, can you clarify for me where the heck this code goes?! In the expresison Builder or what? Thank you SO much. – rick (19 mins ago)
In Access, I think from the graphical Query Builder thing's menu, select edit|SQL, and just type. And never go back to graphical!
You're a hard-charging forward-thinking entrepreneurially-minded man on the move! This is not your father's Oldsmobile! You wouldn't use an on-screen keyboard to type a document, dragging and dropping letters on the page, would you?! So why do that to build a SQL Query? Get into SQL! AS SEEN ON TV! All the cool kids and hep cats are doin' it! Order NOW!
You can use format, for example:
Format([REPORTDATE],"mmm yy")
Or Month:
SELECT * FROM Table WHERE Month([REPORTDATE]) = 10
An outline of query that may suit, paste this into the SQL view of
the query design window, changing table to the name of your table:
SELECT Format([REPORTDATE],"yyyy mm"), Count([ReportDate])
FROM Table
GROUP BY Format([REPORTDATE],"yyyy mm")
I wouldn't do this in the report's recordsource. I'd make the recordsource a regular SELECT statement and use the report's sorting/grouping. If you group on a date field (one that is really date type), you get the choice to GROUP ON:
Each Value (default)
Year
Qtr
Month
Week
Day
Hour
Minute
I think this is faster than a GROUP BY on a function, but someone who was interested should actually try it.
Certainly if your SELECT with GROUP BY has no WHERE clause, it's going to be a lot more efficient if you run the report with filtered values.