sql - select data from 2 tables - php

I have 2 tables - chats_topices and chats_replies
I would like to select all chats_topices fields + the field createDate (timestamp) from chats_replies which closest to the current date.
chats_replies contain field CHATID that connect between the tables
$sql = "SELECT *
FROM `chats_topics` AS topics, `chats_replies` AS replies
WHERE (".$search.") AND
(topics.id = replies.chatID) AND
(XXXX)
ORDER BY topics.createDate DESC";

It's bad practice to use SELECT * in live code, I'd go with something like this;
SELECT topics.Field1, topics.Field2, MAX(replies.createDate) createDate
FROM `chats_topics` AS topics
LEFT JOIN `chats_replies` AS replies
ON topics.id = replies.chatID
WHERE (".$search.")
AND (topics.id = replies.chatID)
AND (XXXX)
GROUP BY topics.Field1, topics.Field2
ORDER BY topics.createDate DESC
Add in your fields that you need to the select and also add them in the group by.

Rich Benner gave you a good join statement for this particular problem. I would like to follow up and attach an image I have found useful when making join statements in the hopes that it might help in the future. I don't remember where I got this picture (although you can see a copyright on the bottom).

Related

how do sql join limit on one of the tables

I want to ask how sql join uses limits on one table
I have searched Google but the query I did was different and that made me confused
$queryAnime = "SELECT *
FROM `anime`
JOIN `episode` ON `anime`.`link` = `episode`.`idanime`
ORDER BY `anime`.`id` DESC
";
$anime = $this->db->query($queryAnime)->result_array();
when I add a limit in the normal way only 1 array appears
I let 'anime' appear all and 'episodes' only show one array
and sorry my English is bad I hope you understand and dabat helps me
If I understand your question correctly, you need to specify the columns you need in the Select statements and not use *, and use a Select Distinct
So for example
SELECT DISTINCT `show_name`,`eposode`
FROM `anime` JOIN `episode`
ON `anime`.`link` = `episode`.`idanime`
ORDER BY `anime`.`id` DESC

Multi-Table, Multi-WHERE and SELECT MySQL query

So, I am trying to select some data from 4 tables using a query I have attempted to throw together.
SELECT *
FROM cards
LEFT JOIN cards_viewers ON cards.card_id = cards_viewers.card_id
(SELECT *
FROM folders
WHERE folder_id = cards.card_folderID)
(SELECT user_firstName,
user_lastName,
user_avatar
FROM user_data
WHERE user_id = cards_viewers.user_id)
WHERE cards_viewers.user_id = '.$u_id.'
ORDER BY cards.card_lastUpdated DESC
Basically, the query selects data from the four tables depending on the user_id in table user_data. I have attempted to initially fetch all data from the tables cards, and cards_viewers, and have went on to use this data to select values from the other tables (user_data and folders).
The query is wrong, I know that. I have learnt the majority of basic MySQL, but I am still struggling with more complex queries like the one I am trying to write now. What query can I use to select the data I want?
Links to any documentation to parts of queries would prove very useful in helping me learn how to create queries in future, rather than just relying on StackOverflow.
Many thanks.
You don't need "MULTI-WHERE" but multiple joins, you just need to keep doing joins until you get the tables you need.
Here's an example:
SELECT *
FROM cards LEFT JOIN cards_viewers
ON cards.card_id = cards_viewers.card_id
LEFT JOIN folders
ON folders.folder_id = cards.card_folderID
LEFT JOIN user_data
ON user_id = cards_viewers.user_id
WHERE cards_viewers.user_id = '.$u_id.'
ORDER BY cards.card_lastUpdated DESC
To custom the fields you want to get just change * for the name of the field being careful about ambiguous column naming.
For further information check MySql Joins. Hope this helped you :)

Ordering By Another Table Column If Exists

I'm putting together a simple forum script with topics/posts. I'm trying to order topics by latest post and I've had some luck with the answer in the following question: MYSQL Order from another Table, but the problem I have is that some topics don't have any posts yet, so the query doesn't select those topics at all.
Current coding is:
SELECT DISTINCT forum.*
FROM forum
INNER JOIN forum_posts
ON forum.id = forum_posts.parent_id
GROUP BY forum.id
ORDER BY forum_posts.parent_id DESC,
forum_posts.time_created DESC
LIMIT ?,?
I want to tell the ORDER BY to order by forum.time_created if there are no matches in forum_posts.parent_id for a topic.
On a side note, I would also like to know how to put a WHERE clause into this query as well. I want to only get rows from forum table "WHERE access <= ?", but can't work out where to put that snippet in.
Any help much appreciated!
EDIT:
Target is to return topics (from forum table)
According to following details:
WHERE forum.access <= ?
LIMIT ?,?
ORDER BY
Latest Post From forum_posts table with forum_posts.parent_id matching on forum.id,
or forum.time_created
EDIT 2:
An example SQLfiddle with relevant data. This doesn't work as the order should really come out as 11,10,9,1,2
http://sqlfiddle.com/#!2/83535/2
Have a look at this: http://sqlfiddle.com/#!2/be909/1
Here's my final query:
SELECT forum.*, recent_forum_posts.time_created as latest_post
FROM forum
LEFT JOIN (SELECT MAX(forum_posts.time_created) as time_created, forum_posts.parent_id
FROM forum_posts
GROUP BY forum_posts.parent_id) AS recent_forum_posts
ON forum.id = recent_forum_posts.parent_id
WHERE forum.access > 2
ORDER BY recent_forum_posts.time_created IS NULL DESC,
recent_forum_posts.time_created DESC,
forum.time_created DESC
LIMIT 5
Essentially, the subquery (the bit in brackets after LEFT JOIN) selects the most recent post for each parent_id from the forum_posts table.
That is then LEFT JOINed (as we want to list all forum's even if there are no posts yet).

mySQL logic: output of table join not correct

I am trying to query two tables: finished_events and flagged_events. 1st of all I need everything related to the company_id so
SELECT *
FROM finished_events
WHERE company_id=$id
ORDER by schedule, timestamp
I then changed this to:
SELECT * FROM finished_events
INNER JOIN flagged_events
ON finished_events.company_id=flagged_events.company_id
WHERE finished_events.company_id=$id
ORDER by finished_events.schedule, finished_events.timestamp
I have tried using FULL JOIN, LEFT JOIN, and RIGHT JOINs all unsuccessful. Specifically what I want is to get is a combined effort of the following code:
$sql = "SELECT *
FROM finished_events
WHERE company_id=$id
ORDER by schedule, time_stamp";
$flagged_sql = "SELECT *
FROM flagged_events
WHERE company_id=$id
ORDER by schedule, time_stamp";
The tables are a bit different so UNION won't work here. I can post dummy database entries but this won't be of too much help as I need all from both tables. The 2 links between the tables would be the company_id and the schedule columns. Essentially what is going on behind the scenes is timestamps being put into a different table to which I then process either into finished_events or flagged_events. Flagged events will need the user to do something about it until it is a finished event. So this script is generating the data for the GUI, hence why I need to query both tables and create an associative array of customer details then an array of events (from these 2 tables). So creating the assoc_array is no problem I just need to get this query to spit out all the events and order them correctly. Let me know if you need anything specific to solve this one, thanks :)
EDIT
SQL Fiddle: http://sqlfiddle.com/#!2/d4c30/1
this almost fixes it but not quite right, it repeats entries at the bottom
If I understood correctly, this may be useful for you:
SELECT a.* FROM (
SELECT *, 'finished' as event_type FROM finished_events
UNION
SELECT *, 'flagged' as event_type FROM flagged_events) a
ORDER BY a.schedule, a.time_stamp

MySQL LEFT JOIN, INNER JOIN etc, complicated query, PHP + MySQL for a forum

So I've got a little forum I'm trying to get data for, there are 4 tables, forum, forum_posts, forum_threads and users. What i'm trying to do is to get the latest post for each forum and giving the user a sneak peek of that post, i want to get the number of posts and number of threads in each forum aswell. Also, i want to do this in one query. So here's what i came up with:
SELECT lfx_forum_posts.*, lfx_forum.*, COUNT(lfx_forum_posts.pid) as posts_count,
lfx_users.username,
lfx_users.uid,
lfx_forum_threads.tid, lfx_forum_threads.parent_forum as t_parent,
lfx_forum_threads.text as t_text, COUNT(lfx_forum_threads.tid) as thread_count
FROM
lfx_forum
LEFT JOIN
(lfx_forum_threads
INNER JOIN
(lfx_forum_posts
INNER JOIN lfx_users
ON lfx_users.uid = lfx_forum_posts.author)
ON lfx_forum_threads.tid = lfx_forum_posts.parent_thread AND lfx_forum_posts.pid =
(SELECT MAX(lfx_forum_posts.pid)
FROM lfx_forum_posts
WHERE lfx_forum_posts.parent_forum = lfx_forum.fid
GROUP BY lfx_forum_posts.parent_forum)
)
ON lfx_forum.fid = lfx_forum_posts.parent_forum
GROUP BY lfx_forum.fid
ORDER BY lfx_forum.fid ASC
This get the latest post in each forum and gives me a sneakpeek of it, the problem is that
lfx_forum_posts.pid =
(SELECT MAX(lfx_forum_posts.pid)
FROM lfx_forum_posts
WHERE lfx_forum_posts.parent_forum = lfx_forum.fid
GROUP BY lfx_forum_posts.parent_forum)
Makes my COUNT(lfx_forum_posts.pid) go to one (aswell as the COUNT(lfx_forum_threads.tid) which isn't how i would like it to work. My question is: is there some somewhat easy way to make it show the correct number and at the same time fetch the correct post info (the latest one that is)?
If something is unclear please tell and i'll try to explain my issue further, it's my first time posting something here.
Hard to get an overview of the structure of your tables with only one big query like that.
Have you considered making a view to make it easier and faster to run the query?
Why do you have to keep it in one query? Personally I find that you can often gain both performance and code-readability by splitting overly complicated queries into more parts.
But hard to get an overview so can't really give a good answer to your question:)
Just add num_posts column to your table. Don't count posts with COUNT().
Can we get some...
Show Tables;
Desc Table lfx_forum_posts;
Desc Table lfx_forum_threads;
Desc Table lfx_forum_users;
Desc Table lfx_forum;
Here's some pseudo code
select f.*, (select count(*) from forum_posts fp where fp.forum_id = f.id) as num_posts,
(select count(*) from forum_threads ft where ft.forum_id = f.id) as num_threads,
(select max(fp.id) from forum_posts fp
where fp.id = f.id
) as latest_post_id,
from forums f;
Then go on to use latest_post_id in a seperate query to get it's information.
if it doesn't like using f before it's declared then make a temporary table for this then you update every time the query is ran.

Categories