PHP / MYSQL Statement so select Max Sum of Join - php

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

Related

Getting multi count from two table and save it in one variable in PHP Codeigniter

I have two tables and I need to get the count of these tables for a condition?
table 1: "tbl_comment" table 2: "tbl_group_comment"
both have some common columns which are login_id of the user,
this is the query:
$param="(SELECT COUNT(*) FROM tbl_comment as t2 WHERE login_id=1) as commentCount, (SELECT COUNT(*) FROM tbl_group_comment as t3 WHERE login_id=1) as commentCount";
$table="`tbl_comment` t2 join `tbl_group_comment`";
$save['value']=$this->Common_model->common_join($param,$table);
this one is not working but if I am changing the second commentCount and keep it as commentCount1 it will give me the value of each table, I want to get the sum of both counts?
is there any specific clause for this matter?
Try this:
select sum(comment_count + group_count) from
((SELECT COUNT(*) as comment_count FROM tbl_comment WHERE login_id=1) A,
(SELECT COUNT(*) as group_count FROM tbl_group_comment WHERE login_id=1)B
);

How we can get the data from the table by limiting the number of identical columns MySql

Yesterday I tried to retrieve data from my db table using 'user_id' as a criterion to limit the amount of data per user.
I tried to get data from table https://prnt.sc/p53zhp in format like this https://prnt.sc/p541wk and limit the number of output records for user_id where limit will be 2 (count(user_id) <= 2), but i don't understand how to do that. What kind of sql request can i use to get this data?
Assuming that your RDBMS, here is a solution yo select only the top 2 records per user. You can use ROW_NUMBER() in a subquery to rank records by id within groups of records having the same user_id, and the filter out unerelevant records in the outer query, like:
SELECT *
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY id)
FROM mytable
) x WHERE rn <= 2
On earlier versions of MySQL, you could use self-LEFT JOIN the table and use GROUP BY and HAVING COUNT(...) < 2 to limit the results to first two records per group:
SELECT
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
FROM mytable t
LEFT JOIN mytable t1 ON t1.user_id = t.user_id AND t1.id > t.id
GROUP BY
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
HAVING COUNT(t1.id) < 2
I don't understand if your problem is a Transact-SQL or your code.
In SQL you can limit record with "LIMIT": https://www.w3schools.com/sql/sql_top.asp
In code, you can use a condition IF.

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 ...

Select unmatched records from two tables of MYSQL

I have two tables Table1 and Table2 with some records
id is the common column in both tables and primarykey is set to this column in table1
There are many records in table1 and some of these records (not all) are updated into table2.
Now I want retrieve from table1 the records not updated into the table2.
For example in table1 there are records 1,2,3,4,5,6,7,8,9
And in table2 there are 3,4,7,9
Now How can I retrieve these records form table1 1,2,5,6 those not updated into table2
I wrote this query :
SELECT Table1.id, Table1.DATE, Table1.C_NAME, Table1.B_NAME
FROM [Table1] INNER JOIN Table2 ON Table1.SLIPNO <>Table2.id;
But the expected result not coming. This query lists all the records repeating each one record manytimes
Can any body give me solution to get the expected result.
select *
from table1
where table1.slip_no NOT IN (select id from table2)
Assuming name of common column is id
Or you can modify your query as
SELECT distinct (Table1.id, Table1.DATE, Table1.C_NAME, Table1.B_NAME)
FROM [Table1]
INNER JOIN Table2 ON Table1.SLIPNO <>Table2.id
A good reference on SQL joins
SELECT t1.*
FROM table1 AS t1
LEFT OUTER JOIN table2 AS t2 USING(id)
WHERE
t2.id IS NULL;
You can use the NOT IN operator on a subquery for table2.
Alternatively, use MINUS with two regular queries listing the ids in each table:
SELECT id FROM table1
MINUS
SELECT id FROM table2;
Try this
SELECT Table1.id, Table1.DATE, Table1.C_NAME, Table1.B_NAME FROM [Table1]
WHERE
NOT EXISTS (SELECT * from Table2 WHERE Table1.SLIPNO !=Table2.id );
You can use the following query
SELECT id FROM database1.table WHERE id NOT IN(SELECT id FROM database2.table)
SELECT child_table.id FROM child_table LEFT JOIN parent_table ON child_table.parent_id = parent_table.id WHERE parent_table.id IS NULL
This left join query returns all the records of the child_table when there is no match in the parent_table. When there is no match, all parent_table fields will be NULL.
inner join will not help. To get unmatched records I tried this:
SELECT
A.ID,A.DATE,A.NAME
FROM TABLE1 A
WHERE CONCAT(A.ID , A.DATE ,A.NAME)
NOT IN
(SELECT CONCAT(B.ID , B.DATE ,B.NAME) as X
from TABLE2 B) ;

Select the latest MySQL Data but unique resort

I have a 1 table database that has a list of advertisements.
I am trying to grab the LATEST advertisement for EACH resort.
I know it should probably be a table database, but how would I go about doing so.
Assuming the Id column is unique:
SELECT T3.*
FROM yourtable AS T3
JOIN
(
SELECT T2.resort, T2.date_added, MAX(T2.id) AS id
FROM yourtable AS T2
JOIN
(
SELECT resort, MAX(date_added) AS date_added
FROM yourtable
GROUP BY resort
) AS T1
ON T1.resort = T2.resort AND T1.date_added = T2.date_added
GROUP BY T2.resort, T2.date_added
) AS T4
ON T4.id = T3.id
select t.*
from YourTable t
join
(select resort, max(dateAdded) dateAdded
from YourTable
group by resort) m on t.dateAdded = m.dateAdded and t.resort = m.resort
order by t.resort
First group the rows by resort to find the max of dateAdded, then query (join) the rows that have the same dateAdded with the max.
One problem is, if the same resort b is added in the same time, twice or more, it will take only the first row. But I think is slightly possible.
Have a look at this article for selecting the "maximum" (say, most recent date) item from a group of items.
Use GROUP BY function
SELECT MAX(dateAdded), resort, linkToUrl FROM `your_table` GROUP BY resort
I think this should do it:
SELECT * FROM advertisements GROUP BY resort ORDER BY dateAdded DESC

Categories