Now I use this code:
$query = mysqli_query($conn, "(SELECT * FROM movies WHERE
MATCH(title) AGAINST('".$_SESSION['mtitle']."' WITH QUERY EXPANSION) AND
id NOT LIKE '".$_SESSION['mid']."')
UNION
(SELECT * FROM movies WHERE category LIKE '%".$cat."%' AND
id NOT LIKE '".$_SESSION['mid']."' ORDER BY RAND()) LIMIT 5");
I would like to list 5 similar movies. When there is 5 or more matches in the first part, it works good. But if isn't, the second selection isn't random, it writes always the same movies in the same sequence.
For example: If I search for Jumanji, the first suggestion is Jumanji, the second is Jumanji: Welcome to the Jungle. But the last 3 is always the same movie.
Group By think be your answer to remove any duplicate values.
`GROUP BY mtitle`
"(SELECT mtitle FROM movies WHERE
MATCH(title) AGAINST('".$_SESSION['mtitle']."' WITH QUERY EXPANSION) AND
id NOT LIKE '".$_SESSION['mid']."')
UNION
(SELECT mtitle FROM movies WHERE category LIKE '%".$cat."%' AND
id NOT LIKE '".$_SESSION['mid']."') GROUP BY mtitle ORDER BY RAND() LIMIT 5"
Related
I want the database to show all the rows, except for the first and last ones, since I have CSS code for them.
I tried this:
SELECT * FROM db
WHERE
keywords LIKE '%example%' LIMIT 9999 OFFSET 1
AND
keywords LIKE '%example%' DESC LIMIT 9999 OFFSET 1
Since the row number may increase I can't write an exact number.
There really is no reason to complicate your query by trying to snip off these values at the SQL level, you could do:
$results = $db->query( /* regular query with all results */ );
array_pop($results);
array_shift($results);
// Now use $results, which now contains only the "middle" content
If you really want it at the DB level, you can use:
SELECT * FROM db
WHERE keywords LIKE '%example%'
AND id <> (SELECT MAX(ID) FROM TABLE)
AND id <> (SELECT MIN(ID) FROM TABLE)
You can use UNION like as
SELECT * FROM db WHERE keywords LIKE '%example%' order by keywords ASC limit 1 UNION SELECT * FROM db WHERE keywords LIKE '%example%' order by keywords DESC limit 1;
You can try this for instance:
SELECT * FROM TABLE WHERE ID != (SELECT MAX(ID) FROM TABLE) LIMIT 1,9844674507370
But like I said in the comment : It is strongly advisable that you handle this with PHP code, to avoid making 2 or more requests
You can do it without using LIMIT AND OFFSET
SELECT * FROM table_name WHERE id != (SELECT MAX(id) FROM table_name) AND id != (SELECT MIN(id) FROM table_name)
SELECT * FROM db
WHERE
keywords LIKE '%example%'
AND
id != (SELECT MAX(id) FROM db)
AND
id != (SELECT MIN(id) FROM db)
here id will be your auto increment key
1st : Simple you can handle this thing in php like below . avoid two query
$last_record =count($records)-1;
$i=0;
foreach($records as $key=>$row)
{
if($i==0){
//apply the css
}
if($i== $last_record ){
//apply the css
}
}
query :
SELECT * FROM db WHERE keywords LIKE '%example%'
$qry="select * from table where category='car' or title='car' or description='car'";
but I want the output to list the rows by category first and then title and then description.
****Edit: actually I am using a like operator to search**
Example:
id category title description
1 car
2 car
3 car
4 car
5 car
6 car
is there any way other than using union?
Thanks in advance.
You can do this using ORDER BY with the right keys. In MySQL, you can do:
ORDER BY (category = 'car') DESC,
(title = 'car') DESC,
(description = 'car') DESC
MySQL treats boolean expressions as integers in a numeric context, with 0 for false and 1 for true. So the DESC puts the true versions first.
You can also simplify the WHERE clause if you like:
WHERE 'car' IN (category, title, description)
You can get this result by using this statement:
SELECT * FROM mytable
WHERE (category='car' OR title='car' OR description='car')
ORDER BY category = 'car' DESC,
title = 'car' DESC,
description = 'car' DESC
How it works?
It will set the orders of data in DESC by sequentially as mentioned in query. You can change the sequence as you want.
Try this ,
SELECT * FROM table where 'car' IN (category, title, description) ORDER BY category DESC, title DESC, description DESC
You can use ORDER BY for multiple columns like:
SELECT * FROM tablename ORDER BY category DESC, title DESC, description DESC
I have tried it and it worked.
You can have multiple ORDER BY clause in your query.
select *from table where category='car' or title='car' or description='car' ORDER BY category DESC, title DESC, description DESC
See this answer for reference. mysql query order by multiple items
Try this Query :
select * from table
where category='car' or title='car' or description='car'
order by 1 desc, 2 desc, 3 desc
I would like to get number of all records and get last record :
$sql_count_sms = "SELECT count(*) as total,content,id FROM android_users_sms WHERE user_id=$id ORDER BY id DESC";
$result_count_sms = mysql_query($sql_count_sms);
$row_num_sms = mysql_fetch_assoc($result_count_sms);
$num_sms = $row_num_sms['total'];
$last_my_sms = $row_num_sms['content'];
I can get number of records but I can't get last content record .
It returns first record !
Where is my wrong ?
Below codes works fine, but I think count(*) is faster than mysql_num_rows .
$sql_count_sms = "SELECT content,id FROM android_users_sms WHERE user_id=$id ORDER BY id DESC";
$result_count_sms = mysql_query($sql_count_sms);
$row_num_sms = mysql_fetch_assoc($result_count_sms);
$num_sms = mysql_num_rows($result_count_sms);
$last_my_sms = $row_num_sms['content'];
Any solution?
The grain of the two results you want is not the same. Without using a sub-query you can't combine an aggregate and a single row into the same result.
Think of the grain as the base unit of the result. The use of GROUP BY and aggregate functions can influence that "grain"... one result row per row on table, or is it grouped by user_id etc... Think of an aggregate function as a form of grouping.
You could break it out into two separate statements:
SELECT count(*) as total FROM android_users_sms WHERE user_id = :id;
SELECT * FROM android_users_sms WHERE user_id = :id ORDER BY id DESC LIMIT 1;
Also, specific to your question, you probably want a LIMIT 1 in combination with the ORDER BY to get just the last row.
Now, counter intuitively perhaps, this should also work:
SELECT count(*), content, id
FROM android_users_sms
WHERE user_id = :id
GROUP BY id, content
ORDER BY id
LIMIT 1;`
This is because we've changed the "grain" with the GROUP BY. This is the real nuance and I feel like this could probably be explained better than I am doing now.
You could also do this with a sub query like so:
SELECT aus.*,
(SELECT count(*) as total FROM android_users_sms WHERE user_id = :id) AS s1
FROM android_users_sms AS aus
WHERE user_id = :id ORDER BY id DESC LIMIT 1;
First I need to get exact match like
SELECT * FROM movies WHERE title='STRING' ORDER BY x DESC
and then append to these results query with LIKE match
SELECT * FROM movies WHERE title LIKE '%STRING&' AND title<>'STRING' ORDER BY x DESC
and limit these results with maximum of 10 results.
UNION wont`t do the jobs as it sorts all results together and returns wrong order (I need exact match first, then with LIKE)
SELECT * FROM movies WHERE title='STRING' UNION
SELECT * FROM movies WHERE title LIKE '%STRING%' ORDER BY x DESC LIMIT 10
The best solution I got is to use multi_query()
$query = "SELECT * FROM movies WHERE title='STRING' ORDER BY x DESC; ";
$query .= "SELECT * FROM movies WHERE title LIKE '%STRING%' AND title<>'red' ORDER BY x DESC";
$Dbi->multi_query($query);
do {
$sql = $Dbi->store_result();
while($x = $sql->fetch_array()) {
...
}
} while($Dbi->next_result());
but in this case it is not possible to use any mysql inside the inner loop and there also must be better looking solution!
You can do this with one query, by using the order by clause:
SELECT *
FROM movies
WHERE title like '%STRING%'
ORDER BY title = 'STRING' desc,
title like '%STRING%' desc
LIMIT 10;
The first clause in the ORDER BY puts the exact matches first. The second then orders by the partial matches. The WHERE clause ensures that there is a match of some kind.
You don't need the UNION, it's accessing the same table twice:
SELECT *
FROM movies
WHERE title LIKE '%STRING&'
ORDER BY CASE WHEN title='STRING' THEN 1 ELSE 2 END
LIMIT 10
(SELECT * FROM movies WHERE title='STRING')
UNION
(SELECT * FROM movies WHERE title LIKE '%STRING%' ORDER BY x DESC LIMIT 10)
i have a MySql table that consists of 2 basic things:
The id and a value.
To show that on my page, i need to select, for example, the last 100 rows on reversed order.
So imagine that someone is putting data on it:
Id, value
1, 10
2, 9
3, 21
4, 15
i need, to select the last "3" rows (LIMIT + ORDER Clause), but not like this: 4,3,2 but like this: 2,3,4.
I know how to do that on code, but maybe there is a simple solution for that on Mysql and i don`t know.
Thanks
My SQL Query is like this right now:
SELECT `Data`.`id`, `Data`.`log_id`, `Data`.`value`, `Data`.`created` FROM `control_panel`.`datas` AS `Data` WHERE `Data`.`id` > 1000 AND `Data`.`log_id` = (2) ORDER BY `Data`.`id` DESC LIMIT 100
You need to wrap the first ORDER BY in a subselect which will return a limited selection ordered in descending order, then you can order that result in the outer query in ascending order:
SELECT
a.*
FROM
(
SELECT id, value
FROM tbl
ORDER BY id DESC
LIMIT 3
) a
ORDER BY
a.id
One way to do this would be with a sub-select.
SELECT *
FROM (SELECT * FROM table_name ORDER BY id DESC LIMIT 3) tmp
ORDER BY id ASC
simply
SELECT t.*
(SELECT * FROM table_name
ORDER BY column_name DESC
LIMIT 0,3) t
ORDER BY t.column_name ASC
use DESC to descending order, ASC to increasing order