Mysql date formatting and ordering - php

I have a table where the dating is not standard and need to somehow organise the rows by date and time.
job_date | job_time
=========================
12/12/2012 | 10.30am
11/10/2012 | 9.00pm
14/11/2012 | 11.50pm
Is there any way of formatting these within mysql. I have looked at the DATE_FORMAT() function but the examples I have found don't seem to relate to the format within my tables.

SELECT *, STR_TO_DATE(CONCAT(job_date,' ',job_time), 'Y-m-d H:i:s') AS date_format from table ORDER BY date_format DESC

The key method is STR_TO_DATE.
I will give you two solutions :
first : if you don't want to change your database :
SELECT jobdate, STR_TO_DATE(job_time,'%h:%i%p')AS real_job_time FROM yourtable ORDER BY real_job_time;
second : if you can modify your database, use the TIME format :
ALTER TABLE yourtable
MODIFY COLUMN job_time TIME NOT NULL;
UPDATE yourtable SET job_time = STR_TO_DATE(job_time,'%h:%i%p');
and to select
SELECT jobdate,job_time FROM yourtable ORDER BY job_time
I think the second solution is by far the best and that you should choose it.

Obviously storing it as a correct date would be a lot better and result in quicker queries.
SELECT *
FROM table
ORDER BY substr(job_date, -4), substr(job_date, 4, 2), substr(job_date, 1, 2)

Related

Parse SQL results by month using timestamp MySQL

I have a small problem with SQL. I need to select ID of rows and group them into arrays (or something) BY MONTH? I have a timestamp column there.
So if there are rows like this:
ID Timestamp
1 blalba(1.10.2017)
2 blabla(2.10.2017)
3 blabla(1.5.1996)
The output would be like
array(
[5.1996] => array([3]),
[10.2017] => array([1,2]);
)
(Or something like this).
Is this possible in PHP using some PHP libraries? Or Do I have to implement my own class doing this?
You are probably looking for group_concat
select group_concat(id separator ', ') as myList,
DATE_FORMAT(Timestamp, '%Y-%m') from <YOUR_TABLE>
GROUP BY DATE_FORMAT(Timestamp, '%Y-%m');
Well you might be handle this on the MySQL side by ordering by month/year:
SELECT
ID, Timestamp
FROM yourTable
ORDER BY
DATE_FORMAT(Timestamp, '%Y-%m');
This query would return a result set to PHP which would be ordered such that all records in the same month and year would be clustered together. You could then just iterate this result set and process the records as you want.

How to query data between to dates having a timestamp field in the table?

I just want to fetch the customer details from the customer table in between two dates with BETWEEN CLAUSE : the datatype of the created_Date field is timestamp and the default value is CURRENT_TIMESTAMP. I wrote the code like below:
SELECT membership_id FROM customers WHERE DATE_FORMAT( created_Date,
'%Y-%m-%d' ) BETWEEN '2016-05-07' AND '2016-06-08'
but even the above code not fetch data,
and when I do the below query
SELECT * FROM customers WHERE created_Date like'%2016-05-16%';
it works,
so from my knowledge there are some bug in BETWEEN CLAUSE.
anyone can help me?
No need for any conversion. Keep the timestamp field as is and provide the date parameters as string literals
SELECT id,created_Date FROM customers
WHERE created_Date BETWEEN '2016-05-07' AND '2016-05-08'
MySQL's type system can (and should) handle that.
see http://sqlfiddle.com/#!9/691df/1
p.s.: The second parameter could be '2016-05-08 23:59:59' to include the whole may 8th.

How to show all the other results after Group By

I "Group By" all the deals in my database by store. How can I show all the other deals who where not grouped after the query?
This is the query I'm using:
$query = mysql_query("SELECT * FROM deals WHERE DATE_FORMAT(expiration_date,'%Y-%m-%d %H:%i:%s') >= NOW() $cat ORDER BY deal_id ASC") or die(mysql_error());
On a slightly different note, a query like this to retrieve records based on date is bad.
SELECT *
FROM deals
WHERE DATE_FORMAT(expiration_date,'%Y-%m-%d %H:%i:%s') >= NOW()
AND cat1 LIKE '%$geef%'
ORDER BY deal_id ASC
What is the format of your expiration date? Given that you are passing it to DATE_FORMAT I would assume it is a DATE or DATETIME type. Wrapping your expiration_date in DATE_FORMAT means the optimiser cannot use an index on that field, forcing a full table scan. This is bad news!
You will get the same result with the DATE_FORMAT removed -
SELECT *
FROM deals
WHERE expiration_date >= NOW()
AND cat1 LIKE '%$geef%'
ORDER BY deal_id ASC
and now the optimiser will be able to use an index that contains expiration_date as the first field in the index.
The fact that you have a field called cat1 leads me to think that you may have other category fields. Again, this is bad news. Repeating groups across columns are not your friend. They make all sorts of things harder than they need to be and they are inefficient. Have a read of this article on First Normal Form.

Getting the result of a MySql query order by date when the date field can contain strings differents than dates

I have a date field on my Sql table that is actually a text field, thats because there sometimes I save dates like 10/28/2011 and sometimes strings like present.
It is possible without touching the table structure, and maybe just with the sql query having the result correct organanized by date? Where present is the max value and then the dates in decreasing order.
If you really can't sort the data type out on those string date columns then this might help:
select t.*,
case when date_end = 'present' then curdate()
else convert(concat(substr(date_end,7,4),'-',substr(date_end,1,2),'-' ,substr(date_end,4,2)),date) end as "realDate"
from myTable t
order by "realDate" desc;
Right. I'm off to go and say 100 Hail Marys to the MySQL database god now. Ugh.
Best way would be :
fix the db and add proper date fields (add proper date or datetime field and update values from text fields and format them to be dates on the fly)
keep your present status in a text field and you can use that as a extra condition
I know you asked for a way to sort it correctly as a text column, but I really don't think that's the right way to this.
I agree with #stivlo. It is very easy to update the database to deal with this is a better way. You can either:
Convert the column to a real date, and use NULL to represent "present" instead of the string "present".
Or, if you need NULL reserved for some other meaning, you can convert the column to a real date, and add additional boolean flag columns to specify when the dates are "present".
Either way, you should definitely convert those text fields to real dates.
select job_desc, data_begin, data_end from table where data_end = 'present'
union
select job_desc, data_begin, cast(data_end as date) data_end from table where data_end <> 'present' order by data_end desc
Not sure if syntax is completely correct, so you might want to check the mySql 'union' syntax
Another solution might be using coalesce for 'present':
select cast(coalesce(data_end,now()) as date) data_end from table order by data_end desc
this way the column gets interpreted as dates and 'present' gets replaced with the present date

Select Mulitple Records based on One record's column value

I have a table which contains related records (multiple revisions of the same record). Each record has a string field that resembles a date (date, time, and microtime). I want to select all records that are older than a specific date. If a record has a related record newer than the specific date, I do not want to select any of those related records. Any ideas for that select statement? Eventually, it will be a REMOVE statement.
Edit: Some Sample Rows
id shared_id date type other_data...
1 2 2010-01-01 01:02:03.1234567 original ...
2 3 2010-01-15 11:12:03.1234733 original ...
3 2 2010-02-01 03:04:04.5465654 amendment ...
If my cut-off date was "2010-01-31", I would want to select id #2 only because id #1 has an amendment newer than the cut-off date.
I found this link helping me generate the select statement.
SELECT DISTINCT T.shared_id,T.date,T.id
FROM table T WHERE T.date = (
SELECT MAX( date ) FROM table WHERE shared_id = T.shared_id )
AND T.date < 'my_cut_off_date_string'
This seems to work for me. Thanks for everyone's help.
Maybe you can try the DATEDIFF() function, check this out:
Link 1
Or this one: Link 2
Or maybe you can try the classic query (SELECT FROM table WHERE data <= anotherdata), but in this case you need to convert both data in timestamp format
DELETE from tablename where relatedField = 'relatedValue' AND dateField <= dateToDeleteFrom
Something along those lines should do what you need it to do, if I understand your scenario. If you provide a sample data set I can adjust the statement to more accurately represent your need, but I think this is a good starting point.
HTH,
Jc

Categories