I have a database my_db and in it two tables t1 and t2.
t1 has two columns ID and count. ID is a list of some integers, say 1,3,4,6,7,8,9 and count is all 0s by default.
t2 also has two columns, ID2 which has a list of integers which are same as that of ID in t1. But, it is possible that they may repeat or may not be present. The second column contains some value, that isn't of much importance to this question. Clarification: ID2 can be 1,1,3,4,3,1,9,8,7,7,7.
Now, what I need to do is for every ID in t1 I need to fill in count, i.e., the number of occurrences of ID as ID2 in t2.
Running a loop through all the values in ID2 and incrementing by 1 every time in corresponding count ought to do it. But I'm unable to code it up, being new to php and sql. I can work in one table. How to work across multiple?
Maybe you can try MySQL update join?
UPDATE t1
LEFT JOIN (SELECT id2,
Count(1) AS num
FROM t2
GROUP BY id2) ref
ON t1.id = ref.id2
SET t1.count = ref.num
Please correct me if I'm wrong.
As I have understand your question is that, you need to count all ID's from Table t2 by looking ID in table t1 and then you want to insert the count of all ID's in your count column of table t1.
<?php
$query = mysql_query("SELECT * from t1");
while($record = mysql_fetch_array($query )) {
$query2 = mysql_query("SELECT COUNT(*) from t2 WHERE id='".$record['ID']."'");
$fetch = mysql_fetch_array($query2);
$count = $fetch['COUNT(*)'];
$query3 = mysql_query("UPDATE t1 SET count='".$count."' WHERE id='".$record['ID']."'");
}
?>
If you get any error. You may inform me.
Hope it will works for you.
Thanks
Another answer (with sub query)
update d1
set d1.count_d1 = (select count(d2.id)
from d2
where d2.id = d1.id group by d1.id)
SQL Fiddle
Are you looking for this :
select t1.id,count(t2.id) as total_record_in_t2
from t1
left join t2 on (t1.id=t2.id)
group by t1.id;
SQL Fiddle Example - Click to See
Here is the sql part.
First get the count of occurences of ID2 in t2:
select id2, count(*) from ts group by id2;
Then loop over the result and update t1:
update t1 set count = $value where id1 = $id2
Related
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 ...
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
So, I have next table structure :
Is there a way to make SQL query that counts simillar hashes in r_hash column, than founds this hash in hash column and returns an uid, and count of hashes?
For example - uid - 21520578; type - 1; count - 7?
Try the below query
SELECT T1.uid, T1.type, T2.count
FROM table T1,
(
SELECT r_hash, COUNT(*) AS count
FROM table
GROUP BY r_hash
) T2
WHERE T1.hash = T2.r_hash
You can do that by using join
SELECT t1.uid, t1.type, COUNT(t2.id) as `count`
FROM table AS t1
LEFT JOIN table AS t2 ON t2.r_hash = t1.hash
GROUP BY t1.id
I am not tested this query.
Edit: with left join you also receive rows with count = 0.
Ive looked at other questions and answers but still dont understand which brings me here.
I have one data base two tables. lets say table1 and table2 from database.
I'm looking to grab all the information from table1 and only one column from table2 that coincides with the correct row in table1.
Example which I know is wrong:
SELECT table1.*, table2.time_stamp FROM table1, table2
WHERE table1.ticket_id=$var AND table1.user_id = table2.user_id
Basically select data from table1 then use a value from the selected table to grab the related data from table2 and join them to output them as one mysql_query. Im sure its simple and has been asked before.
edit:
I dont receive an error. SQL just returns noting. log form of this would be:
$sqlResults = mysql_query("SELECT table1.* FROM table1 WHERE table1.ticket_id=$var")
while($rowResult = mysql_fetch_array( $sqlResults )) {
$userID = $rowResult['user_id'];
$sqlResults2 = mysql_query("SELECT table2.time_stamp FROM table2
WHERE table2.user_id=$userID")
}
I want to combine that into one sql statement so i dont have to hit table2 for every row table1 has
Use a JOIN to bind the rows from table2 to those from table1:
SELECT t1.*, t2.time_stamp FROM table1 t1
JOIN table2 t2 ON t1.user_id = t2.user_id
WHERE t1.ticket_id=$var
Im trying to construct a query that goes over 3 tables and im COMPLETELY stumped ... my knowledge limit is basic 1 table query and i need some help before i stick my head in a blender.
I have the following query
SELECT * FROM internalrole WHERE introle = $imarole
Im fine with that part .. its the next thats getting me all stressed.
That query returns the following columns ( id, user_id, introle, proven, used )
What i then need to do is take the user_id from the results returned and use it to get the following
SELECT * FROM users WHERE id = user_id(from previous query) AND archive = 0 and status = 8
I need to put that into 1 query, but wait, theres more .... from the results there, i need to check if that user's 'id' is in the availability table, if it is, check the date ( column name is date ) and if it matches todays date, dont return that one user.
I need to put all that in one query :S ... i have NO IDEA how to do it, thinking about it makes my head shake ... If someone could help me out, i would be eternaly grateful.
Cheers,
Use INNER JOIN, which links tables to each other based on a common attribute (typically a primary - foreign key relationship)
say an attribute, 'id', links table1 and table2
SELECT t1.att1, t2.att2
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id --essentially, this links ids that are equal with each other together to make one large table row
To add more tables, just add more join clauses.
SELECT u.*
FROM internalrole ir
INNER JOIN users u
ON ir.user_id = u.id
AND u.archive = 0
AND u.status = 8
LEFT JOIN availability a
ON ir.user_id = a.user_id
AND a.date = CURDATE()
WHERE ir.introle = $imarole
AND a.user_id IS NULL /* User does NOT exist in availability table w/ today's date */
EDIT: This second query is based on the comments below, asking to show only users who do exist in the availability table.
SELECT u.*
FROM internalrole ir
INNER JOIN users u
ON ir.user_id = u.id
AND u.archive = 0
AND u.status = 8
INNER JOIN availability a
ON ir.user_id = a.user_id
WHERE ir.introle = $imarole
Hmm, maybe something like this
SELECT * FROM users WHERE id IN (SELECT user_id FROM internalrole WHERE introle = $imarole) AND archive = 0 and status = 8;
A handy thing for me to remember is that tables are essentially arrays in SQL.
HTH!
Nested queries are your friend.
SELECT * FROM users WHERE id in (SELECT user_id FROM internalrole WHERE introle = $imarole) AND archive = 0 and status = 8
Alternatively joins:
SELECT * FROM users INNER JOIN internalrole ON users.id = internalrole.user_id WHERE internalrole.user_id = $imarole AND users.archive = 0 and users.status = 8