In my database I have the date of each customer order stored in the format 02 Mar 2015
I have data from March and April and I want a query that will return just those 2 months. Once I have data for May it will return the three months etc.
The SQL syntax which I am trying to use is:
SELECT DISTINCT MONTH(DATE_FORMAT(date,'%d %b %y')) FROM orders
However this returns 0 rows. I presume this is an issue with date format.
EDIT:
Sample data from table:
id | date | time | order_id | item | quantity
1 | 02 Mar 2015 | 14:22 | 1029 | clasico | 9
1 | 05 Apr 2015 | 13:58 | 1029 | hindu | 10
try
SELECT DISTINCT MONTH(`order_date`) FROM `orders`
where order_date is the date field in orders
Note: The answer assumes the date column is a varchar rather than a datetime datatype.
The DATE_FORMAT() function is used to display date/time data in different formats. Note: This assumes the data is a datetime data type.
The STR_TO_DATE() returns a datetime value by taking a string and a specific format string as arguments. See the code below in action in the SQL Fiddle demo.
select DISTINCT MONTH(STR_TO_DATE(date, '%d %b %y')) from orders
Related
I have a mysql "users" table like this example:
id | user | created
100 | user001 | [27-01-2016 04:30 PM]
101 | user005 | [19-05-2017 09:28 AM]
102 | user019 | [09-10-2015 03:29 PM]
103 | user029 | [18-11-2017 05:40 PM]
And I want to get this table in descending order by created row like this:
id | user | created
103 | user029 | [18-11-2017 05:40 PM]
101 | user005 | [19-05-2017 09:28 AM]
100 | user001 | [27-01-2016 04:30 PM]
102 | user019 | [09-10-2015 03:29 PM]
I tried with DATE_FORMAT:
SELECT id,user,DATE_FORMAT(created,"%d %m %Y") AS created FROM users ORDER by created desc
But it shows nothing, how can I get it?
I'd like some help.
This works:
SELECT `id`, `user`, DATE_FORMAT(STR_TO_DATE(MID(`created`, 2, 19), '%d-%m-%Y %h:%i %p'), '%d-%m-%Y %h:%i %p')
AS `created:` FROM `users` ORDER BY STR_TO_DATE(`created:`,'%d-%m-%Y %h:%i %p') DESC
Here is a working SQL Fiddle.
Explanation:
The MID() MySQL function returns the middle part of a string, so we easily stripped out the []. After that, the STR_TO_DATE() function parses the returned string into DATETIME format (the %p is for AM/PM). The returning value is not properly formatted, at least not in the way you would wish to have it. So we then use DATE_FORMAT() to format the output. In the end, we use STR_TO_DATE() once again for the ordering since created: is returned as string.
I also changed your created output column to created: since it will not work if they are all the same name.
Your created date format isn't correct, you should alter the table and change the field from varchar/char(string) to timestamp type. I have already tried converting your string dates with 'STR_TO_DATE()' but it returns null because the format doesn't match either timestamp, date or time formats. Its always best practice to store dates/datetime as either date or timestamp data types. You can always apply formatting functions later in query to output dates to any desired format.
for e.g
SELECT *
FROM api_call_log
WHERE account_sid='XXXXXXXXXXXX' AND
created_time >= 01-02-2016 00:00:00 AND
created_time <= 31-02-2016 23:59:59
ALLOW FILTERING
I am getting records from first month as well though I searched for second month.
It's difficult to say without seeing your table structure or relevant portions of your result set. But I did notice that you are not specifying a GMT offset, which means you are effectively querying by your default local offset. The problem, is that Cassandra stores by GMT+0000.
For example, if you have a negative GMT offset of say -0600 (like me), a query for GMT-0600 would miss 6-hours-worth of data from February 1st. For instance, if I have a row out there for 2016-02-01 01:00:00+0000, this query will not return it:
aploetz#cqlsh:stackoverflow> SELECT * FROm events WHERe monthbucket='201602'
AND eventdate >= '2016-02-01 00:00:00';
monthbucket | eventdate | beginend | eventid | eventname
-------------+-----------+----------+---------+-----------
(0 rows)
And that's because 2016-02-01 01:00:00+0000 is essentially 2016-01-31 19:00:00-0600. So if I add the GMT offset of 0000, I see the row.
aploetz#cqlsh:stackoverflow> SELECT * FROm events WHERe monthbucket='201602'
AND eventdate >= '2016-02-01 00:00:00+0000';
monthbucket | eventdate | beginend | eventid | eventname
-------------+--------------------------+----------+--------------------------------------+-------------------
201602 | 2016-02-01 01:00:00+0000 | b | 78d2c2b7-c4ec-408f-be37-eccc0c05727d | test month border
(1 rows)
My guess, is that you probably have the opposite problem (extra rows vs. missing rows) due to having a positive GMT offset. Not specifying your offset in your query could be why it is including rows from the previous month. And if that's the case, then you may want those rows.
Also, don't use ALLOW FILTERING. Like ever.
Try this
SELECT * FROM api_call_log WHERE account_sid='XXXXXXXXXXXX' AND jobs.created_at between '01-02-2016 00:00:00' and '31-02-2016 23:59:59';
And also check the DATE/TIME format of the date column
I'm attempting to aggregate payment histories under a single due date and create an html table similarly displayed below.
+--------------+---------------+----------------+
| Date Due | Amount Paid | Date Paid |
+--------------+---------------+----------------+
| Nov, 1 2012 | $10 | Oct, 21 2012 |
| | $15 | Oct, 18 2012 |
| Oct, 14 2012 | $20 | Oct, 13 2012 |
| | $20 | Sep, 3 2012 |
+--------------+---------------+----------------+
The problem I am facing is this:
The date due, amount paid, and date paid data fields are all in the same table row. The date due does not necessarily correspond to when the actual payment was made (maybe a payment was made 3 weeks late). Or... maybe two payments were received within the time frame of a single payment date due.
How can I efficiently tackle a problem like this and display it in a table? I've tried a few ways already and the code is too system process intensive.
EDIT: The rows in the table of the database currently look something like this:
+--------------+---------------+----------------+
| Date Due | Amount Paid | Date Paid |
+--------------+---------------+----------------+
| Nov, 29 2012 | $10 | Oct, 21 2012 |
| Nov, 15 2012 | $15 | Oct, 18 2012 |
| Nov, 1 2012 | $20 | Oct, 13 2012 |
| Oct, 14 2012 | $20 | Sep, 3 2012 |
+--------------+---------------+----------------+
But the customer has to pay $50 for every due date. In this case, the customer split up their payments and it did not apply to the current due date because of the way the data is formatted in the table.
Unfortunately, I can not change anything in the database.
The query will be
select * from table_name order by Date_Due ASC,Date_Paid ASC , Amount_Paid ASC
This query first do order by of Date_Due by ascending and after that by Date_Paid and Amount_Paid.
Assuming your query is on a single flat table, it sounds like you simply want each due date to display only once (instead of with every row).
If thats correct, I think you should just approach the problem in your php code that constructs your table rather than trying achieve this in your mysql result.
Assume I have a log of something. Each record has a timestamp (MySQL data type TIMESTAMP) in the format date('Y-m-d H:i:s') (from PHP). I need to produce a report that looks like this:
===========================================
| Date | Total Sales |
===========================================
| Thursday, Dec 1, 2011 | 100 |
-------------------------------------------
| Friday, Dec 2, 2011 | 200 |
-------------------------------------------
| Saturday, Dec 3, 2011 | 150 |
-------------------------------------------
... and so on ...
I assume I have to dynamically build the SQL from PHP, which is OK. I'm just not sure what the SQL would look like. Ideas?
How to count the number of records per day
This is what I originally thought you wanted. I'm leaving it here because it might be useful to other people.
You have a bunch of timestamps. You want to group them by individual days and get the number of records per day.
Assuming your timestamp field is named ts, you can do something like this:
SELECT COUNT(*), DAY(ts), MONTH(ts), YEAR(ts) FROM tableName
GROUP BY YEAR(ts), MONTH(ts), DAY(ts);
How to generate daily reports for individual people
Ok this is what you really wanted. Let's draw a sample table with some records:
ts person sales
2011-12-01 10:00:00 John 10
2011-12-01 10:30:00 Mary 25
2011-12-01 11:00:00 John 20
2011-12-02 14:00:00 John 40
To get the daily totals for a particular person, you would do:
SELECT SUM(sales), DAY(ts), MONTH(ts), YEAR(ts) FROM tableName
WHERE person='John'
GROUP BY YEAR(ts), MONTH(ts), DAY(ts);
This is selecting records where person is John, grouped by unique days, and summing the sales value for those records. If you want reports for every person combined, just remove the WHERE clause.
Final note
You can simplify your SQL a little bit if you use the DATE type instead of the DATETIME type. I'm selecting and grouping by the day, month and year which I need to get using three separate functions. If you're using the DATE type, calling these functions would be unnecessary and I could just select and group by ts directly. It's up to you how you want to represent your data.
I'm trying to enter a date in a mysql table
`ssdate` datetime
The function that produces the date can output it in 3 formats:
1276142400000
Thu Jun 10 00:00:00 GMT-0400 2010
Fri Jun 4 2010
I'm wondering which of these would be easiest to convert to this field format?
Since I'm trying to save only the date, is there a better option than datetime that would work with one of these output formats?
You can use the third format:
date('Y-m-d H:i:s', strtotime('Fri Jun 4 2010'));
Just put the result in your datetime field. If you're going to use a date field instead you can do
date('Y-m-d', strtotime('Fri Jun 4 2010'));
The easiest way would probably be FROM_UNIXTIME(), but 1276142400000 does not appear to be a Unix timestamp:
mysql> SELECT FROM_UNIXTIME(1276142400000);
+------------------------------+
| FROM_UNIXTIME(1276142400000) |
+------------------------------+
| NULL |
+------------------------------+
1 row in set (0.00 sec)
Perhaps it's a Unix timestamp mutiplied by 1000:
mysql> SELECT FROM_UNIXTIME(1276142400000/1000);
+-----------------------------------+
| FROM_UNIXTIME(1276142400000/1000) |
+-----------------------------------+
| 2010-06-10 06:00:00 |
+-----------------------------------+
1 row in set (0.05 sec)
And, if unsure, you always have STR_TO_DATE():
mysql> SELECT STR_TO_DATE('Fri Jun 4 2010', '%a %b %e %Y');
+----------------------------------------------+
| STR_TO_DATE('Fri Jun 4 2010', '%a %b %e %Y') |
+----------------------------------------------+
| 2010-06-04 |
+----------------------------------------------+
1 row in set (0.00 sec)
You can set your column as a varchar(14), will work perfectly with your first format output.
In database I would store time values in in DATETIME field, mainly because of built-in methods for date manipulations (INTERVAL, etc.). One possible alternative is to store UNIX timestamp as numeric value, but I wouldn't recommend that. If in doubt, choose standard solutions.
As for date format to convert from, I would definitely go with UNIX timestamp (#1 option in your case, multiplied by 1000 I guess) as most universal one. All other formats are locale- and timezone-dependent, which is a possible source for a lots of headaches in the future.