Change order of records from MySQL in PHP - php

How can I change the order by time either in MySQL or in the While Loop?
I have a query like
`"SELECT `start-time` from `table_name`"`
and my start-time will be in format 02:00pm, 02:00am, 05:00am, in likewise. If that's just number without am/pm I can use order by.
Or, if the above way not possible, can I use PHP to order the start time in while loop?
I am using the following way to retrieve the data
$doquery = mysql_query("SELECT `start-time` FROM `table_name`");
while($fetch_query = mysql_fetch_array($doquery)){
echo $fetch_query['start-time'];
}
Thanks

Are you storing your times as TIMESTAMP in MySQL? If not, you should be. The most efficient way to sort the results is going to be by adding an ORDER BY clause to your SQL statement. For instance, to sort so that the most recent times occur first in the result set, try this:
SELECT `start-time` FROM `table_name` ORDER BY `start-time` DESC;
To order so that the most recent times occur last in the result set, change the query to:
SELECT `start-time` FROM `table_name` ORDER BY `start-time` ASC;
The other thing that I would encourage you to explore is PDO. All of the mysql_* PHP functions are deprecated. Prepared queries are a lot more secure and flexible. There are a lot of tutorials out there... this one looks alright: http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html Anyway hope that helps. Happy coding.

If it is simply a string you could use STR_TO_DATE or CASE WHEN, like:
Using STR_TO_DATE
SELECT `start-time` from `table_name`
ORDER BY STR_TO_DATE(start-time,'%h.%i%p')
Using CASE
SELECT `start-time` from `table_name`
ORDER BY
CASE WHEN start-time LIKE '%am%'
THEN 0
ELSE 1
END, start-time
Bu I agree with others you could probably store this as TIMESTAMP and use mySQLi or PDO for your database handling in php.

Related

Distinct function broken in MySQL 5.7

I have the following code that has stopped working since MySQL 5.7 upgrade:
$myDB->contentArray = $myDB->executeAssoc("
SELECT DISTINCT(YEAR(displayDate)) as year FROM
`inlineItemData_standardList`
WHERE `inlineItemGroupID` = $inlineItemGroupID
ORDER BY `displayDate` desc");
Could anyone show me how I would replace the DISTINCT part in this? I have searched around and can find others with the same issue but without a lot of PHP knowledge, I can't seem to implement the correct thing. I tried using GROUP BY 'YEAR(displayDate)) as year' but can't seem to get it to work. Thanks in advance.
The ORDER BY clause of a SELECT DISTINCT query must be consistent with the SELECT clause.
So:
SELECT DISTINCT YEAR(displayDate) as year
FROM inlineItemData_standardList
WHERE inlineItemGroupID = ?
ORDER BY YEAR(displayDate) DESC
-- Or: ORDER BY `year` DESC
Side note: use prepared statements! Do not concatenate variables in the query string: this is both inefficient and unsafe. Recommended reading: How can I prevent SQL injection in PHP?

if else clause in sql, automatic rebuild of indexes

I am in need of a sql construct which gives the following functionality.
select if-expression if status='regular' else else-expression
from table-name ;
This operation will be used very frequently. So, I am considering building an index for this operation.
But, I heard that indexes are not rebuilt after table is being updated. Is there a way we can have automatically rebuild indexes?
Thanks in advance
The translation in SQL of your statement is:
select (case when status = 'regular' then <if-expression> else <else-expression> end)
from tablename;
An index will not help with this query, because you are not limiting the rows in any way. An index can help when you have filters in a where clause, joins, and correlated subqueries (and sometimes I think with group by).
And as MarcB points out in a comment, MySQL (and all other databases) keep indexes up to date for insert, update, and delete operations.
You did not provide a more detailed example.
There are several alternative solutions to your idea, not just the "use-the-index-luke-solution". And depends a lot on your database.
Another alternative could be using "union". In some circumstances could use too much resources, in others, may be the optimal solution, even if using too many records.
SELECT
<if-expression>
FROM
MyTable
WHERE
(MyTable.status = 'regular')
UNION
SELECT
<else-expression>
FROM
MyTable
WHERE
(MyTable.status <> 'regular')
And, in some circumstances, you may also add
SELECT
<if-expression>
FROM
MyTable
WHERE
(MyTable.status = 'regular')
ORDER BY <indexed-fields-used-in-expression>
UNION
SELECT
<else-expression>
FROM
MyTable
WHERE
(MyTable.status <> 'regular')
ORDER BY <indexed-fields-used-in-expression>
Cheers.

Using multiple SELECT statements to narrow results

I have a database with some properties that have been sold. They each have a date associated with it which is what I need to use to narrow the search results.
Basically I have a query:
$query = "SELECT * from newsales WHERE city = '".$_GET['location']."'";
And what I need to do is, from the results returned from the above query, I need to further narrow it down to be within the past 90 days.
So it'll find the city, and then it needs to ONLY get the ones from the last 90 days. How do I combine SELECT statements to narrow the results down?
Thanks!
You could use the SQL AND operator.
Doc: http://dev.mysql.com/doc/refman/5.1/en/logical-operators.html
Your query would be than:
$query = "SELECT * from newsales WHERE city = '".$_GET['location']."' AND date > '".$oldestdate."';
Set $date to the oldes date, in your case 90 days before today. According to your dateformat in your mysql database you have to calculate this in a timestamp or datetime.
You don't need to combine SELECT statements, just make a more complex WHERE clause using the boolean AND operator:
$query = "
SELECT *
FROM newsales
WHERE
city = '".$_GET['location']."'
AND date > '".$oldestdate."'
";
I'd advise you to read up on SQL injection as well - if you use $_GET directly like that, someone can come to your website and basically type in any SQL statement they want.
The easiest way, assuming you are using mysqli_* functions (which have replaced the mysql_* functions but can be used mostly interchangeably) is mysqli_real_escape_string(), e.g. city = '" . mysqli_real_escape_string($_GET['location']) . "'.
Combining results of multiple SELECT statements means you need to use UNION.
Please see this : http://dev.mysql.com/doc/refman/5.0/en/union.html
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

This query on mysql is taking forever to execute

im making a simple admin module to query the database to show the results. Im using this query via php:
SELECT
*
FROM myTable
WHERE id in(SELECT
id_registro
FROM myOtherTable
where id_forma='".$id_club."' and fecha_visita Like '%".$hoy."%'
)
order by id DESC
The result shows, however, it takes very long like 2 minutes..Anyone can help me out?
Thanks!
Without seeing your database, it is hard to find a way to make it faster.
Maybe you can try to turn your WHERE IN to INNER JOIN. To something like this
SELECT * FROM myTable INNER JOIN myOtherTable
ON (myTable.id = myOtherTable.id_registro)
WHERE myOtherTable.id_forma = '$id_club'
AND myOtherTable.fecha_visita LIKE '%$hoy%'
ORDER BY myTable.id DESC
Noted that you should sanitize your variable before putting it SQL query or using PDO prepare statement.
Sub Queries takes always time, so its better to ignore them as much as possible.
Try to optimize your query by checking its cardinality,possible keys getting implemented by DESC or EXPLAIN , and if necessary use FORCE INDEX over possible keys.
and I guess you can modify your query as:
SELECT
*
FROM myTable
inner join id_registro
on (id = id_forma )
where
id_forma='".$id_club."' and fecha_visita Like '%".$hoy."%'
order by id DESC
LIKE in mysql may take a long time ,with or without index.
Do u have a very large DB?

PHP, MYSQL: Order by date but empty dates last not first

I fetch an array with todo titles and due dates from MySQL. I want to order it by date and have the oldest on top. But there are some todos without a date. These todos I don't want to show at first positions but rather at the bottom of my list. Unfortunately MySQL put the empty ones first.
Is there any way I can do it in one query (can't use MySQLi, using CI's ActiveRecord). I could run a second query for all todos without dates and put them at the bottom. But I'd like to make it in one query – if possible?
You can do it in MySQL with the ORDER BY clause. Sort by NULL first, then the date.
SELECT * FROM your_table ORDER BY (date_column IS NULL), date_column ASC
Note: This assumes rows without a date are NULL.
Yes
SELECT *
FROM table
ORDER BY CASE your_date
WHEN '' THEN 'b'
ELSE 'a'
END,
date ASC
possibly add a NVL( thedate, to_date('2099-12-31','yyyy-mm-dd')) in the order by clause
You can use this:
select * from my_table
order by if(isnull(my_field),1,0),my_field;
Well, as a pure MySQL answer, I would probably do it like this.
select todo.title, todo.due_date
from todo
order by ifnull(todo.due_date, '9999-12-31')

Categories