MySQL don't select a row - php

I need to get the titles of 3 recent posts, but leave out a specific one, if it comes up as one of the 3 most recent ones.
I got this:
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
ORDER BY
date DESC
LIMIT
3
This works fine, but I need to tell if to leave out the row where "postID = $postID"
"$postID" is the post that shouldn't be displayed and is defined before.
Thanks!

Add another condition to the where clause to filter that specific postId
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND
postID <> $postID
ORDER BY
date DESC
LIMIT
3

This should do the trick:
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND
postID != $postID
ORDER BY
date DESC
LIMIT
3

Am I understanding you correctly? You just want to omit the postID equal to $postID?
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND
postID <> $postID
ORDER BY
date DESC
LIMIT
3

This query returns the expected results using the <> operator:
SELECT
postID,
title
FROM
posts
WHERE
categoryID = $categoryID
AND postID <> $postID
ORDER BY
date DESC
LIMIT
3

Related

ORDER before SELECT statement?

I have this query which works great
$sub_query = "SELECT * FROM posts WHERE post_status = 'published' AND
post_user = '{$out}' ORDER BY post_id DESC ";
The query brings back all of a specific users posts ordered by descending post id. The problem is it loops through every post user and orders them accordingly but I want the newest post overall not just the newest post per user.
Here is an image of the results to hopefully help explain better
You can see the query runs for a specific user and then moves on to the next user where I am trying to get the newest post id first
I have tried to follow this similar question but it brought back the same results.
$sub_query = "SELECT * FROM (SELECT * FROM posts ORDER BY post_id DESC)
T WHERE post_status = 'published' AND post_user = '{$out}' ";
Would I be able to order all of the selected posts first? Then use my where statement?
If you want the newest post per user, then remove the where and add a limit:
SELECT p.*
FROM posts p
WHERE p.post_status = 'published'
ORDER BY post_id DESC
LIMIT 1;
I did not understand if what you are looking for is
1) the list of the last post per user
2) the list of all posts sorted by the newest (regardless the user)
In both case you don't need to loop all users, you can extract data ordered just using the query itself (i strongely advise you on this solution).
option 1:
SELECT *
FROM posts
WHERE post_id IN (
SELECT MAX(post_id)
FROM posts
WHERE post_status = 'published'
GROUP BY post_user
)
ORDER BY post_user ASC
option 2:
SELECT *
FROM posts
WHERE post_status = 'published'
post_id DESC

mysql: order the result by column name

$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

Pulling latest post from table

All,
I am trying to display the latest post from my authors.
The posts are in one table, the author in another. The queries used were: join on a column called content_id, and I am trying to work with MAX(item_date) which is the date the post was published.
Here are some queries I am running and the output, I seem to be getting everything except the latest posts from all authors:
First (and this bit is working) we need to get information about the author:
$query="SELECT content_id, title, source_image, url FROM content_detail where approved='y'";
$result1 = $mysqli->query($query) or die($mysqli->error.__LINE__);
// GOING THROUGH THE DATA
if($result1->num_rows > 0) {
while($fetch=mysqli_fetch_array($result1)) {
$title=$fetch['title'];
$feed_rss=$fetch['url'];
$content_id=$fetch['content_id'];
$source_image=$fetch['source_image'];
Now on that basis lets get the posts, round 1:
$query2 = "SELECT item_id, item_title, MAX(item_date) as item_date from posts WHERE content_id='$content_id' GROUP BY content_id";
$result2 = $mysqli->query($query2) or die($mysqli->error.__LINE__);
if($result2->num_rows > 0) {
while($rows2=mysqli_fetch_array($result2)) {
$item_id = $rows2['item_id'];
$item_title = $rows2['item_title'];
$item_date = $rows2['item_date']; `
This pulls back an in interesting set of results, the latest date of a post from an author, but not the latest title!
I have tried GROUP BY item_title and content_id to no avail.
The following pulls back just records that have more than one date in the database, the problem is (as this is new) some authors only have one post, these are not being displayed:
$query2 = "SELECT item_id, item_title, item_date FROM posts AS a WHERE content_id = content_id AND item_date = (
SELECT MAX(item_date)
FROM rssingest AS b
)
";
I have tried:
ORDER BY DATE DESC LIMIT 1
at the end of my queries to no avail.
item_date is a DATE type in the table.
Any help would be greatly appreciated!
Thanks,
You are running this query to get the maximum date:
SELECT item_id, item_title, MAX(item_date) as item_date
from posts
WHERE content_id = '$content_id'
GROUP BY content_id;
Of course you don't get the right item_title. It is not mentioned in the group by clause and has no aggregation function. So, you are using a MySQL extension (this query would fail in other databases).
You can get the most recent title using the substring_index()/group_concat() trick:
SELECT max(item_id),
substring_index(group_concat(item_title separator '|' order by item_date desc), '|', 1) as last_title,
MAX(item_date) as item_date
from posts
WHERE content_id = '$content_id'
GROUP BY content_id;
This will return one row. But, if there is only one row that you want, you can do:
SELECT p.*
from posts p
WHERE p.content_id = '$content_id'
ORDER BY item_date desc
LIMIT 1;
The previous version will generalize if you add a group by statement.
You need to join your posts table with itself to grab only the newest post for each content_id (which I believe is the author).
$query2 = "SELECT posts.item_id, posts.item_title, posts.item_date from posts
join (select max(item_id) max_id, content_id from posts group by content_id) maxid
on maxid.content_id=posts.content_id and maxid.max_id=posts.item_id
WHERE content_id='$content_id' ";
This opens the door for further optimization. You could grab the authors and their last post in one run.
SELECT content_detail.content_id,
content_detail.title,
content_detail.source_image,
content_detail.url ,
posts.item_id,
posts.item_title,
posts.item_date
FROM content_detail
join posts on content_detail.content_id=posts.content_id
join (select max(item_id) max_id, content_id from posts group by content_id) maxid
on maxid.content_id=posts.content_id and maxid.max_id=posts.item_id
where content_detail.approved='y'
But this could be an overstatement. You should of course try it yourself :)

SQL Table Structure for news site

I want to make a fast table structure for news site with php and mysql. My database structure is ID, title, content, cat_ids (; separedet IDs of categories - ;5;10;15;20;), active, publish_date.
I want to make a fast query to select news from this table. Something like that:
SELECT id
FROM news
WHERE cat_ids LIKE '%;15;%'
AND active = 1
AND publish_date < NOW()
ORDER by publish_date DESC
LIMIT 0, 10
But if my table is 2-3GB the query is very slow. I need some ideas to make structure and make the select faster.
Instead of using cat_ids column, try creating a news_cats table with news_id and cat_id, and using this query:
SELECT id
FROM news JOIN news_cats ON news_id = id
WHERE cat_id = 15
AND active = 1
AND publish_date < NOW()
ORDER by publish_date DESC
LIMIT 0, 10
Some suggestions as below:
1) Create index on "active" field
2) Create index on "publish_date" field
3) Create separate table for category and news relation and remove "cat_ids" field from news table
New table might look like below:
news_category_ids
news_id
category_id
It can have multiple rows for each news_id, if news item falls in 3 categories, it will have 3 rows
Then use SQL like below:
SELECT news.id
FROM news INNER JOIN news_category_ids ON news.id = news_category_ids.news_id
WHERE 1
AND news.active = 1
AND news_category_ids.cat_id = 15
AND news.publish_date < NOW()
ORDER by news.publish_date DESC
LIMIT 0, 10

Select max 5 integers from set of 20

I'm trying to select the 5 most viewed articles out of a list of the 20 most recent entries in a table. My table structure is essentially this:
id | date | title | content | views
My first thought was just to use an inner select to get the 20 most recent articles, then select from that, but I have yet to have any luck.
//doesn't work (my version of mysql doesn't support LIMIT in sub queries)
$recent = "(SELECT id FROM news ORDER BY date DESC LIMIT 20)";
$result = $db->query("SELECT id, title, date, content FROM news WHERE id IN $recent ORDER BY views DESC LIMIT ".self::RECENT_MAX);
//neither does this (syntax error # 'OFFSET 20')
$recent = "(SELECT MAX(date) FROM news ORDER BY date DESC OFFSET 20)";
$result = $db->query("SELECT id, title, date, content FROM news WHERE date > $recent ORDER BY views DESC LIMIT ".self::RECENT_MAX);
Anyone got any suggestions on how you would structure this query?
I just tested this and it works
SELECT *
FROM (
SELECT *
FROM news
ORDER BY id DESC
LIMIT 0, 20
) lasttwenty
ORDER BY views DESC
LIMIT 0, 5
Server version: 5.0.51a-3ubuntu5.4
If you're having a lot of issues getting it to work through SQL, I'd suggest just grabbing the 20 most recent articles from the database, then process it in PHP to find the 5 most-viewed. You could either loop over the rows, or just load it all into an array and sort it.
Since I can't think of any way to do that in a single query, I suggest either selecting the top 5 in code, or doing it using two queries, something like:
$items = $db->query("SELECT id FROM news ORDER BY date DESC LIMIT 20");
$recent = array();
foreach ($items->fetchAll() as $item) { $recent[] = $item['id']; }
$recent = "('".join("','", $recent)."')";
$result = $db->query("SELECT id, title, date, content FROM news WHERE id IN {$recent} ORDER BY views DESC LIMIT ".self::RECENT_MAX);
Why don't you run the first (inner) query separately, and create the second query programmatically?
$ids = array();
$result = $db->query("SELECT id FROM news ORDER BY date DESC LIMIT 20");
while ($row = $result->fetch()) {
$ids[] = $row[0];
}
$ids = implode(',', $ids);
$result = $db->query("SELECT id, title, date, content FROM news WHERE id IN ($ids) ORDER BY views DESC LIMIT ".self::RECENT_MAX);
Or something of this nature...
Update: Or you could just simply fetch the first 20 sorted by date, then sort thr result array by views in PHP, and finally take the 5 topmost items (I guess this is what SilentGhost meant in the comment).
Try this...
select top 5 number from
(
select
top 20 (ID) as number
from
news order by date desc
)
as number
EDIT FOR MS SQL
Use the LIMIT for MYSQL

Categories