count comments for each row Union and Left Join - php

See sample data below.
Here is what I have so far.
SELECT
table1.stuff,
COUNT(table1.id) AS row_count,
COUNT(comment_table.id) AS comment_count
FROM table1
LEFT JOIN comment_table
ON table1.id = comment_table.page_id
AND comment_table.page_type = 'nofun'
UNION
SELECT
table2.stuff,
COUNT(table2.id) AS row_count,
COUNT(comment_table.id) AS comment_count
FROM table2
LEFT JOIN comment_table
ON table2.id = comment_table.page_id
AND comment_table.page_type = 'fun'
Sample data table1:
id stuff
1 the stuff
2 other stuff
Sample data table2:
id stuff
1 the stuff still
2 other stuff still
Sample data comment_table:
id page_id page_type comment
5 1 fun Ello
6 2 nofun hey janis
Desired Results:
stuff comment_count row_count
the stuff still 1 2
other stuff 1 0
logic of sample data:
I would like to return all rows from table1 and table2. I would also like to get the total number of comments from comment_table associated with each row from table1 and table2 and lastly, count the total number of row returned from table1 and table2.
table1 and table2 have a "page_type", in this case table1 is "nofun" and table2 is "fun". Each comment_table row is related to either table1 or table2 by it's "page_type" AND "page_id", row id of either table1 or table2.
table1 id:2 has one comment (comment_table id:6) and table2 id:1 has one comment (comment_table id:5).
The desired results table shows two sample rows with 'stuff' from table1 and table2 and also the comment count for each row, and a total number of rows.
I do not believe I am wholly understanding the left join. How can I accomplish my goal.?

BIG thanks to #Solarflare for pointing out the lack of GROUP BY.
Here is what I needed:
SELECT
`table1`.`stuff`,
COUNT(`comment_table`.`id`) AS comment_count
FROM `table1`
LEFT JOIN `comment_table`
ON `table1.id` = `comment_table`.`page_id`
AND `comment_table`.`page_type` = 'nofun'
GROUP BY `table1`.`id`
UNION
SELECT
`table2`.`stuff`,
COUNT(`comment_table`.`id`) AS comment_count
FROM `table2`
LEFT JOIN `comment_table`
ON `table2`.`id` = `comment_table`.`page_id`
AND `comment_table`.`page_type` = 'fun'
GROUP BY `table2`.`id`
Data Results:
stuff comment_count
the stuff still 1
other stuff 1
I removed "row_count" since the data is properly grouped I can get the total row count from $page->num_rows.
Thank you everyone who took their time to view my question and certainly those who took the time to comment.

Related

mysql fetch data from two tables

Please find picture to get more clarification on what I am asking
Click here
Let me tell you full description
I have two tables -
Table1 contains book_id and book_name
second table -
Table2 contains book_id, stock and cs_id
I want when someone choose cs_id so result displayed in terms of book_name and not book_id
I'm sorry for short description...
I have two tables in mysql database -
table1
SN ID Name
1 E-11 ELC
2 E-13 ELX
3 D-41 DME
and table2
SN ID CS_ID
1 E-11 C01
2 E-13 C01
3 D-41 C54
How to get result of all name from table1 using one cs_id from table2 using php.
Please help.
Thanks in advance!
Here what I'm using
$query = "SELECT table1.id, table2.name FROM table1 INNER JOIN table2 ON table1.id = table2.id WHERE table1.cs_id=$cs_id'
this is showing me 0 result.
Use TABLE LEFT JOIN
LIKE
select tb1.name,tb2.ID FROM TABLE1 as tb1 LEFT JOIN TABLE2 as tb2 ON tb1.ID=tb2.ID where tb2.CS_ID='$request_id';
I hope its work

Getting data from one table based on results of another SQL PHP

I know this involves JOINS but I can't seem to find a working solution to what I'm trying to do.
I have 2 custom tables :
table1 | table2
---------------------
id id
uid uid
track_id track_id
date date
art active
info
blah
blah2
First I want to select everything WHERE uid=55 AND active=1 from table2 :
$tracks = $wpdb->get_results( "SELECT * FROM table2 WHERE uid = 55 AND active = 1");
And then match the track_id from table2 with results from table1 so I can traverse the table1 data.
I know I can do it like this :
foreach( $tracks as $track ) {
$this_track = $track->track_id;
$results = $wpdb->get_results( "SELECT * FROM table1 WHERE track_id = $this_track");
// Do stuff here
}
But this is the part where it gets tricky...
I then want to ORDER the $results from table1 by date DESC from table2
And this is where I'm lost...
Effectively I want (pseudo code) :
$results = $wpdb->get_results( "SELECT * FROM table1 WHERE track_id = $this_track" ORDER BY date DESC FROM table2);
As well as that last bit, I know I can do this entire routine with JOINS to keep this all in one query and make it way more efficient but I just don't know how.
So just to be clear, my overall routine should be like this :
Get all instances of track_id from table2 where user_id=55 and active=1, then use those results to match the track_id to every result in table1 with the same track_id and then sort the results by date back over from table2
Psuedo code, I know it contains nonsense :
$finalresults = $wpdb->get_results( "SELECT * FROM table2 where uid=55 AND active=1 THEN SELECT * FROM table1 WHERE track_id = "the track_id from the first query" THEN ORDER BY date DESC FROM table2);
Try with this query
SELECT t1.* ,t2.date AS t2date, t2.active FROM table2 AS t2 INNER JOIN table1 AS t1 ON (t1.track_id = t2.track_id) WHERE t2.uid=55 AND t2.active=1 ORDER BY t2.date DESC;
Edit: Explanation of what this query is doing. and inverted the order of the tables retrieved in the query (this don't affect the final datatset, i did this to make to follow the logic of the explanation.
1.- Begin with retrieving all rows from table2 (theres is no specific reason because i used table2 over table1, I'm only following an logical order), using the criteria that you specified iud=55 and active=1
SELECT * FROM table2 WHERE uid=55 AND active=1;
2.- but as you said you need to expand the data retrieved in table2 with some information in table1, that's exactly what it is the directive JOIN made, and we are using INNER JOIN because this type of JOIN will show rows ONLY if data for the uid=55 is present on table1, if there is NO data for the uid=55 present on both TABLES then mysql wil show empty the recordset (0 Rows selected).
in the ON(...) part I specify which criteria mysql will use to compara both tables for match in this case will compare that track_id on table2 it is the same that the specified on table1, if this codition is met then mysql considers it as a match.
anly for convenience and because i'm adding a Second table i gave an Alias to each one t1 and t2.
then the query now seems like this
SELECT * FROM table2 AS t2 INNER JOIN table1 AS t1 ON(t1.track.id = t2.track_id) WHERE t2.uid=55 AND t2.active=1;
3.- but then raise a problem, both tables has rows with the same field names, and this is something that DBMS don't like in their queries, to avoid this situation in the query i only show the fields (id, uid and track_id) from one table in this case t1 (t1.*) and only show the fields that doesn't have this problem from t2 (t2.date AS t2date, t2.active). in this way mysql won't throw any error.
SELECT t1.* ,t2.date AS t2date, t2.active FROM table2 AS t2 INNER JOIN table1 AS t1 ON (t1.track_id = t2.track_id) WHERE t2.uid=55 AND t2.active=1;
4.- for the final step i specify to mysql that i want all found rows ordered descent by a field in the table2;
ORDER BY t2.date DESC;
then this criteria will be applied to the whole selected rows. and the final query has this form.
SELECT t1.* ,t2.date AS t2date, t2.active FROM table2 AS t2 INNER JOIN table1 AS t1 ON (t1.track_id = t2.track_id) WHERE t2.uid=55 AND t2.active=1 ORDER BY t2.date DESC;
if is not completely clear you can ask ...

getting secondary name using sub query

I have two tables, 1st table holds the categories list and 2nd table holds the profile information along with 1st table category id as a foreign key. As follow
Table1
id CATEGORY
1 first
2 second
Table2
id CATEGORY name phone
1 2 John 9999999999
how to retrieve table 2 records along with category name (not id:2 as shown in table 2)
I tried this,
SELECT category, name, phone FROM table2;
I need to see following line as result
second, john, 9999999999
get me out of this step, thanks in advance.
What you need is a JOIN, which means you "combine" two tables by linking rows from one table to rows from another table based on some criterion.
In your case, the criterion is that the value of CATEGORY in table2 must equal the value of ID in table1, which is expressed as follows:
SELECT table1.category,
table2.name,
table2.phone
FROM table2
JOIN table1
ON table2.category = table1.id
If needed, you can add a WHERE clause to limit the result to specific rows, e.g. WHERE table1.id = 9999999999 would filter the rows that have category 9999999999.
This should work:
SELECT t1.category, t2.name, t2.phone
FROM table2 AS t2
JOIN table1 AS t1
ON t1.id = t2.category
You can make an INNER JOIN and get the category from the Table 1, like this:
SELECT tb1.category, tb2.name, tb2.phone
FROM table2 tb2
INNER JOIN table1 tb1 on tb2.category = tb1.id
WHERE tb2.id = 1;
Hope it helps!

Filtering duplicates while joining tables

I need to select data from both tables and display it but my PHP file seems to be posting duplicates. I want to be able to pick up all of the descriptions and relate it to the ID's which are used in table1.
I managed to get some of it to work but it displays the name Jake twice is their anyway i can filter out the duplicates.
Thanks
Here is my code
$sql = "SELECT table1.name, table2.description
FROM table1
INNER JOIN table2
on table1.id = table2.customerid";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo $row['name']."<br>";
echo $row['description']."<br>";
}
table1
id name
1 james
2 jake
3 aaron
4 holly
table2
id customerid description
1 1 hey1
2 2 hey2
3 2 hey3
4 3 hey4
5 4 hey5
you can use a DISTINCT constraint.
If two rows are assumed to be "identical" only if the rows have the same values for all columns, you group them in one DISTINCT query:
SELECT DISTINCT table1.name,table2.description
FROM table1
INNER JOIN table2
ON table1.id = table2.customerid
Otherwise, you can use the GROUP BY statement. But then a problem arises: which "description" will you pick? Since there are two for Jake. MySQL has implemented several function aggregates. A potential candidate is MIN which returns the alphabetically sorted minimum. The query then reads:
SELECT table1.name,MIN(table2.description)
FROM table1
INNER JOIN table2
ON table1.id = table2.customerid
GROUP BY table1.name

PHP / MYSQL Statement so select Max Sum of Join

I have Problems with a select statement, as a little help here are the important columns:
Table1
ID NAME
TABLE 2
ID U_ID COUNTER
The ID of Table 1 Matches the U_ID of Table 2. Table 2 contains many entries for the same u_id.
What I want to do is to get the Name of the "user" (table 1) who has in sum the max. counter.
What I got since now is the join of the tables (Where clause depends on other rows which are not important for the problem).
Can anyone help me on this issue?
So what you need is an aggregate of an aggregate (max of sum of column). The easiest will be to create a view providing the sum and u_id end then select the max of it:
create view table2sums
as
select u_id, sum(counter) as total
from table2
group by u_id;
and then
select t1.name
from table1 t1, table2sums t2
where t1.id = t2.u_id
and t2.total >= all (
select total
from table2sums
)
In this special case you can also do it directly:
select t1.name
from table1 t1, table2 t2
where t1.id = t2.u_id
group by t1.name
having sum(t2.counter) >= all (
select sum(counter)
from table2
group by t2.u_id
)
NOTE: The other proposed solutions will show a better performance. My solution only selects the name (which is what you said you wanted) and works in any RDBMS.
There exist RDBMS without the LIMIT possibility.
In the end, I'd say: regard my solution as educational, the others as practical
SELECT name,
SUM(counter) as counter
FROM table1
JOIN table2
ON table1.id = table2.u_id
GROUP BY u_id
ORDER BY counter DESC
LIMIT 1
You can try this:
SELECT name, SUM(counter) as total_counter
FROM table1
JOIN table2
ON table1.id = table2.u_id
GROUP BY u_id
ORDER BY total_counter DESC
LIMIT 1
Working Demo: http://sqlfiddle.com/#!2/45419/4

Categories