Combine to two tables within a single query to order data - php

I have two tables word_term_relationships and word_posts
What I'm doing is using a while loop in order to fetch a certain record from the word_term_relationships table where a certain value is true.
$query = "SELECT object_id
FROM `word_term_relationships`
WHERE `term_taxonomy_id` = '54'";
I then use another query within the loop to use the data that was retrieved from the previous query in order to fetch data from the other table word_posts
$query2 = "SELECT post_title, post_date, post_date_gmt, guid
FROM `word_posts`
WHERE `ID` = '$post_id'";
This I can do and works fine.
The only issue is that I then need to order the results by date and time, I can do this without the while loop and using the ORDER BY function and the word_posts table.
However, I've tried to link the tables within the query like this (below) in order to order the data. But obviously it isn't correct - I just can't pinpoint within the query what is wrong.
$query = "SELECT word_term_relationships.object_id
FROM word_term_relationships
WHERE word_term_relationships.term_taxonomy_id = '54'
ORDER BY word_posts.post_date ASC";
I know the above query is missing something, I was thinking a second where after the ORDER BY word_posts.post_date ASC.

A simple INNER JOIN will solve your problem. Try this,
SELECT a.post_title,
a.post_date,
a.post_date_gmt,
a.guid
FROM word_posts a
INNER JOIN word_term_relationships b
ON a.ID = b.object_id
WHERE b.term_taxonomy_id= '54'
ORDER BY a.post_date ASC

$query = "SELECT post_title
, post_date
, post_date_gmt
, guid
FROM word_posts a INNER JOIN word_term_relationships b on a.ID = b.object_id
WHERE term_taxonomy_id = '54'
ORDER BY a.post_date ASC";

Related

How to display several subcategories and their news in one query?

I have a news site and I am trying to include a block of news in it.
see the image please
I created a category call world news and added subcategories. (Travel, News, Art, Bussines)
I display them one by one, I mean I do a query for each news, that means 4 different queries like below :
$sql = "SELECT posts.post_catId,
posts.post_seo_url,
posts.post_desc,
posts.post_type,
posts.post_status,
posts.post_title,
posts.post_image_url,
categories.catId,
categories.catName,
categories.cat_seo_url
FROM posts
LEFT JOIN categories
ON posts.post_catId = categories.catId
WHERE post_catId = catId AND cat_seo_url = 'art'
AND post_status = ?
ORDER BY post_created_at DESC LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute(['1',]);
if($stmt->rowCount() > 0){
while($row = $stmt->fetch()){
//here
}
}
My question is: is there a way to display them in one query ?
Edit : I want to display 1 news from 4 specific categories with one query instead of 4.
I know I can add a new row to categories table to secify which categories can be displayed.
You 'invert' the query, selecting the categories first and then joining to the posts table, constraining it by the post_seo_url field, like so:
$sql = "SELECT
categories.catId,
categories.catName,
categories.cat_seo_url,
posts.post_catId,
posts.post_seo_url,
posts.post_desc,
posts.post_type,
posts.post_status,
posts.post_title,
posts.post_image_url,
FROM categories
JOIN posts ON posts.post_seo_url = (
SELECT p.post_seo_url FROM posts as p
WHERE categories.catId = p.post_catId
ORDER BY p.post_created_at DESC LIMIT 1
)
WHERE post_status = ?"
Here's a method using ROW_NUMBER() function:
SELECT p.*,
categories.catId,
categories.catName,
categories.cat_seo_url
FROM
(SELECT
ROW_NUMBER() OVER (PARTITION BY posts.post_catId ORDER BY posts.post_created_at DESC) AS RN,
posts.post_catId,
posts.post_seo_url,
posts.post_desc,
posts.post_type,
posts.post_status,
posts.post_title,
posts.post_image_url
FROM posts
WHERE post_status = ? ) p
JOIN categories
ON p.post_catId = categories.catId
WHERE RN=1;
I've made the query on posts table to become a subquery with addition of ROW_NUMBER() function then JOIN it with categories table and added WHERE that only return row number = 1. I've changed the LEFT JOIN to JOIN because I don't see any reason to use LEFT JOIN in this operation. However, if there is a reason, please update it in your question.
Here's a demo fiddle

sorting mysql table by data within a different table

I have to mysql tables and trying to display results of table1 but sorting by table2. For table2 I'm counting all the occurrences of a duplicate id and then display that result descending. Below is as far as I could get and wondering if this can even be done is a single query.
$query = "
SELECT DISTINCT registration.*
FROM registration
INNER JOIN downloads
ON registration.id = downloads.id
GROUP BY downloads.COUNT(id)
ORDER BY downloads.COUNT(id) DESC,
downloads.COUNT(id) DESC
";
I think you want something along these lines:
SELECT Registration.id, Registration.name, Registration.email,
Downloads.document
FROM Registration
JOIN Downloads
ON Downloads.id = Registration.id
JOIN (SELECT id, COUNT(*) as count
FROM Downloads
GROUP BY id) Download_Count
ON Download_Count.id = Registration.id
ORDER BY Download_Count.count DESC
(untested, as it would be nice for the OP to supply sample data and table layouts in the question)

sub queries order by

I am trying get records from question order by sub query (qcat) table. and my code is
"SELECT * FROM question
where survey_name='$_SESSION[ssn_sname]' AND
qcategory IN
( SELECT qcategory FROM qcat
WHERE client_name='$_SESSION[ssn_sname]'
GROUP BY qcategory
ORDER BY p_order
) AND
status='1' AND
survey_name LIKE'%$sname%
LIMIT $start, $limit";
But it did not get results in order.
how can i get rows order by the qcat table?
In the sub query you do not need the GROUP BY clause - This is used for aggregated functions
You also do not need the ORDER BY in the sub query - Let mysql work it out for the in bit
Add the ORDER BY for the whole query. i.e. at the end
So the SQL should be
"SELECT * FROM question
where survey_name='$_SESSION[ssn_sname]' AND
qcategory IN
( SELECT qcategory FROM qcat
WHERE client_name='$_SESSION[ssn_sname]'
) AND
status='1' AND
survey_name LIKE'%$sname%
ORDER BY p_order
LIMIT $start, $limit";
I also think that you may be able to avoid the sub query in the first place. But that would require a little thinking and a bit more knowledge about the tables.
BTW - Note the possibility of SQL injection
You need to join with the qcat table in order to be able to sort on a different column within that table. Try this:
$query = "
SELECT q.id question_id, q.*, c.*
FROM question q
INNER JOIN qcat c ON c.category = q.category
WHERE q.survey_name='$_SESSION[ssn_sname]'
AND c.client_name = '$_SESSION[ssn_sname]'
AND q.status='1'
AND q.survey_name like '%$sname%'
GROUP BY q.id
ORDER BY c.p_order
LIMIT $start, $limit";
Note: Your query is vulnerable to SQL Injection!

using LIMIT and ORDER BY with LEFT JOIN in sql query

I'm a bit new to JOIN and I'm finding it difficult to understand how I can query one table with ORDER BY and LIMIT and using only ORDER BY on my JOINED 'right' table I think it is? So Basically if I was to query the two tables individually I would use these queries:
SELECT * FROM posts ORDER BY dateSubmitted DESC LIMIT ?,5
'?' standing for my bind_param() because I'm creating a pagination. Now for my 'right' Second table:
SELECT * FROM postcomments WHERE postcomments.postID = posts.ID ORDER BY dateSubmitted DESC
As far as my understanding goes to 'link' the two tables together I want to be using LEFT JOIN so that I will receive all my data from the 'left' table (being posts).
SELECT * FROM posts LEFT JOIN postcomments ON postcomments.postID = posts.ID
Now I can do this but I'm unsure where I would but my ORDER BY and LIMIT for both tables?
I've seen several different ways and I think this is what's getting me confused like I've seen this:
SELECT p.* FROM posts p ORDER BY posts.dateSubmitted DESC LIMIT ?,5
LEFT JOIN (SELECT * FROM postcomments
WHERE postscomments.postID = p.ID ORDER BY postcomments.dateSubmitted);
But I'm really unsure how to structure my query :S Any help appreciated :)
It will be at the end like this:
Select * from
(SELECT * FROM posts ORDER BY dateSubmitted DESC LIMIT ?,5) as tempPost
LEFT JOIN postcomments on (postscomments.postID = tempPost.ID)

PHP/MySQL Query In a loop, how to append to just one query?

I have a query to pull all articles out of the database..
$get_articles = $db->query("
SELECT *, a.id AS id, s.type AS type FROM ".$prefix."articles a
LEFT JOIN ".$prefix."sources s ON (s.id = source_id)
WHERE a.type!='trashed' ORDER BY a.timestamp DESC LIMIT $start, $end");
Within the loop of this query, I do then do another query on the same table to find related articles to the 'title' of the article, stored as '$related_phrase'. The query within the loop is:
// get related articles to this entry
$get_related = $db->query("
SELECT *, a.id AS id, MATCH (title, description) AGAINST ('$related_phrase') AS score FROM ".$prefix."articles a
LEFT JOIN ".$prefix."sources s ON (s.id = source_id) WHERE a.type!='trashed' AND MATCH (title, description) AGAINST ('$related_phrase') AND a.id!='$articles[id]' HAVING score > 7
ORDER BY a.timestamp DESC LIMIT 0, 3");
This basically means we have a query in a loop which is causing the pages to load very slowly.
What we want to do, is bring the query from within the loop, in the main query, so it's all working within one query, if that's possible?
Any help very much appreciated!
I don't think you would gain much speed by merging the two queries.
One thing you could try is to get a list of all articles and DISTINCT searchphrases (in e.g. temptable), and then build a query to get all related articles in one single go. Lastly match up related articles with the article list.
try this:
$articles_and_related = $db->query("
SELECT *
FROM ".$prefix."articles art
LEFT JOIN (
SELECT * FROM ".$prefix."articles x
WHERE
score > 7
AND x.type != 'trashed'
AND x.id != art.id
AND MATCH(x.title, x.description) AGAINST (art.title)
LIMIT 3
) rel
LEFT JOIN ".$prefix."sources s2 ON (s2.id = rel.source_id)
LEFT JOIN ".$prefix."sources s ON (s.id = art.source_id)
WHERE
art.type!='trashed'
ORDER BY art.timestamp DESC LIMIT $start, $end");

Categories