Ordering rows by count in a separate pivot table - php

I have a main table: Images and votes.
The votes contains 2 fields: Id, image_id
What I wish to do is query the images table and return them ordered by the amount of votes in the vote table.
Currently:
$stmt = $conn->prepare(
'SELECT *
FROM images
LIMIT 10'
);
I understand basic left joins, but cannot think how to order them by count of votes. Just need a starting example.
Thanks

Assuming that each row in your VOTES table means one vote towards the image, this should work: SQL DEMO
SELECT *, COUNT(v.image_id)
FROM images AS i
LEFT JOIN votes AS v ON i.id=v.image_id
GROUP BY i.id
ORDER BY v.image_id desc

drop table if exists t1;
create table t1 (id int);
insert into t1 values (1), (2), (3);
drop table if exists t2;
create table t2 (id int, img_id int);
insert into t2 values (1, 1), (2, 1), (3, 2), (4,1), (5,3), (6,2);
select *
from t1
left join
(select img_id, count(*) count
from t2
group by img_id) c
on img_id=t1.id
order by count
Demo on sqlfiddle

Related

update user score from other tables

I have a few tables that each have their own scores for each user. I would like to create a trigger that will add up all those scores for each user and put them in a field called score in the users table.
Tables (They essentially have the same fields with a few different ones) :
Table 1 : {id, user_id, score}
Table 2 : {id, user_id, score}
Table 3 : {id, user_id, score}
users : {id, name, overall_score}
// Overall _score has a value already , so i just want to add the score fields from the other tables to this one.
To achieve this lets first write the select query and get sum of all the scores per user from the 3 given tables and this is how it could be done
select u.*, y.total from users u
left join
(
select user_id,sum(score) as total from(
select user_id, score from table_1
union all
select user_id, score from table_2
union all
select user_id, score from table_3
)x group by x.user_id
)y on y.user_id = u.id
Here is the demo http://www.sqlfiddle.com/#!9/6f936/1
Now lets convert the select to an update command and it will be as
update users u
left join
(
select user_id,sum(score) as total from(
select user_id, score from table_1
union all
select user_id, score from table_2
union all
select user_id, score from table_3
)x group by x.user_id
)y on y.user_id = u.id
set u.overall_score = coalesce(y.total,0)
here is the demo http://www.sqlfiddle.com/#!9/c6993/1
To select data from multiple tables, you can use SQL JOINS.
See the example below:
SELECT table1.score, table2.score, table3.score
FROM table1 LEFT JOIN table2
ON table1.id=table2.id LEFT JOIN table3 ON table1.id=table3.id
This code will select the score column from table1, table2, and table3 and create one row per user_id, each containing one score-column/ table (in this case 3/ row). It's almost like having a fourth table containing all the scores, and then when you fetch them in PHP, it'd be like fetching an existing row from the database.
EDIT:
To Update the users table in the same query, you could use something like this:
UPDATE `users`,
(
SELECT table1.id as tid, table1.score as t1,
table2.score as t2, table3.score as t3
FROM table1 LEFT JOIN table2 ON table1.id=table2.id
LEFT JOIN table3 ON table1.id=table3.id
) as total
SET total_score = (t1 + t2 + t3) WHERE id = tid

Selecting specific rows from table

I have the below table (in picture) which is kind of inventory table and shows how many items comes in and how many goes out from stock, and item_id is the foreign key from another table.
I want to select those records that has no out from the stock, in other word i want to select those records which are highlighted in green (in the picture).
Thanks.
Sorry for poor English
The Table
Try this:
Select * from `table` where id in (select id from `table`group by id having sum(out)=0);
for deleting those values use:
delete t1
from `your_table` as t1
join (select item_id from `your_table`group by item_id having sum(item_out)=0) t2 on t1.item_id = t2.item_id
Try this query.
SELECT * FROM 'table_name' where out=0;
You need to join the table to itself: SELECT t.* FROM <your_table> AS t LEFT JOIN <your_table> AS t1 ON t.item_id=t1.item_id WHERE t1.out>0 AND t1.item_id IS NULL

php mysql with left outer join

I have two tables in mysql table1 and table2
table1 have the following fields
Field Type
intProjectId int(11)
intSourceId int(11)
intClientId int(11)
varProject varchar(200)
fltAmount float
varAmountType varchar(50)
dtStart date
dtEnd date
And table 2 have the following fields
Field Type
intPercentageId int(11)
intProjectId int(11)
floatPaymentpercentage float
ddDate datetime
join two table with common project id.If table2 has no records with the particular project id it can joined as null..
Table 1 has project data
Table 2 has its percentage of complettion. (Each project has more than one records. )
Project Id -- common field
Iused the following query
SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.intProjectId = table2.intProjectId
GROUP BY table1.varProject ORDER BY table2.intPercentageId DESC
Here i get the output as percentage table returns the first record for each project. I need the last inserted record for the table 2.
table1 ==> project id 5
In table 2 has 3 records for project Id 5. I want to ge the last record from the table2. Now it returns the first record from table 2
How to change the query. Please help me to fix this.
Calculate the maximum record for each project in table2 and use that information to get the latest record. Here is a method that uses group by:
select t1.*
from table1 t1 join
table2 t2
on t1.intProjectId = t2.intProjectId join
(select t2.intProjectId, max(intPercentageId) as maxpi
from table2 t2
group by t2.intProjectId
) tt2
on t2.intProjectId = tt2.maxpi;
Calculate the maximum record for each project in table2 and use that information to get the latest record. Here is a method that uses group by:
select t1.*
from table1 t1 join
table2 t2
on t1.intProjectId = t2.intProjectId join
(select t2.intProjectId, max(intPercentageId) as maxpi
from table2 t2
group by t2.intProjectId
) tt2
on t2.intProjectId = tt2.maxpi;
Try this
SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.intProjectId = table2.intProjectId
GROUP BY table1.varProject HAVING MAX(table2.intPercentageId)
"Order By" runs after "Group by" has completed, that is why it is not giving the intended result. The change I have suggested will give the row from 2nd table with the highest percentage which as per the scenario should be the last row for the project.

How to fetch row from two tables in single query?

I have three tables
1>EVENT table columns event_id, time
2>EVENT_TYPE1 table columns ref_event_id
3>EVENT_TYPE2 table columns ref_event_id
now what I want to do is to perform a query so that ref_event_id from both tables EVENT_TYPE1 and EVENT_TYPE2 can be compared to EVENT table ,in single query, and results are arranged in ascending order of time.
You can do something like this:
SELECT a.col1, a.col2
FROM EVENT a
LEFT JOIN
(SELECT col1, col2 FROM EVENT_TYPE1
UNION ALL
SELECT col1, col2 FROM EVENT_TYPE2) b ON b.col1 = a.col1 <== Comparison
This creates a single table to join with ordered as you want
SELECT combined.* FROM (
SELECT * from EVENT_TYPE1
UNION
SELECT * from EVENT_TYPE2) AS combined
I'm a little fuzzy on what you mean by 'Compared to Event table'. You can join the result of this inner select to the Event table on event_id = ref_event_id assuming ref_event_id is a foreign key into the event table.
SELECT * FROM (
SELECT * from EVENT_TYPE1
UNION
SELECT * from EVENT_TYPE2) AS combined
JOIN EVENT ON event_id = combined.ref_event_id
ORDER BY combined.time ASC

Selectively delete mostly duplicate records from MySQL

I have a table:
PRICE_UPDATE
id (int 5, auto-increment, primary, unique)
part_number (varchar 10, non-null)
price (float(10,2), non-null)
Some of the part_numbers are duplicated (1 or more duplicate records). Sometimes with the same price, sometimes with different prices.
How can I delete all of the duplicate rows based on part_number, leaving either the highest price or just 1 record if the prices were all the same?
Is this even doable in straight MySQL?
DELETE t1
FROM YourTable t1, YourTable t2
WHERE t1.part_number = t2.part_number
AND (t1.price, t1.id) < (t2.price, t2.id)
From inside, to outside:
Selects the ids with the max price per part_number
Selects the max id with the max price per part_number
Deletes the ids not present in 2.
delete tablename where id not in (
(select max(id) from tablename a
inner join
( select id, max(price)
from tablename
group by part_number ) b on a.id = b.id and a.price = b.price
group by part_number))

Categories