Missing SQL entries when combining LEFT/INNER JOIN + GROUP BY - mysql

I have the following MySQL structure (minimized a lot):
CREATE TABLE `site_movies` (
`id` int(10),
`title` varchar(90),
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
INSERT INTO `site_movies` VALUES(1, 'Borrowers, The');
INSERT INTO `site_movies` VALUES(2, 'Louis C.K.: Chewed Up');
INSERT INTO `site_movies` VALUES(3, 'Louis C.K.: Shameless');
INSERT INTO `site_movies` VALUES(4, 'Vinni-Pukh');
CREATE TABLE `site_movies_directors` (
`id` mediumint(8),
`name` varchar(255),
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
CREATE TABLE `site_movies_directors_connections` (
`movie_id` mediumint(8),
`director_id` mediumint(8)
) ENGINE=MyISAM;
CREATE TABLE `site_movies_seen` (
`object_id` int(10),
`date` varchar(10),
`rating` tinyint(2)
) ENGINE=MyISAM;
INSERT INTO `site_movies_seen` VALUES(1, '0', 4);
INSERT INTO `site_movies_seen` VALUES(2, '1293821757', 5);
INSERT INTO `site_movies_seen` VALUES(3, '1293821758', 7);
INSERT INTO `site_movies_seen` VALUES(4, '0', 6);
And then the following query (also minimized a lot):
SELECT m.title, s.date
FROM site_movies_seen s
INNER JOIN site_movies m ON s.object_id = m.id
LEFT JOIN site_movies_directors_connections AS mdc ON ( m.id = mdc.movie_id )
GROUP BY mdc.movie_id, s.date
ORDER BY s.date ASC
Prints:
title date
Borrowers, The 0
Louis C.K.: Chewed Up 1293821757
Louis C.K.: Shameless 1293821758
Notice that "Vinni-Pukh" is missing because it is the second entry in the _seen table with date = 0. How can I include all entires, even when several entires have the same timestamp?

Change your group by statement to this:
GROUP BY m.id, s.date
Your join condition says m.id = mdc.movie_id, so you might think that these two fields are always equal and therefore it doesn't matter whether you write m.id or mdc.movie_id in your GROUP BY. This is not true because you are using a LEFT JOIN, not an INNER JOIN. This means that mdc.movie_id can be NULL, and all NULL entries go into the same group.
Also, since you aren't selecting any columns from the site_movies_directors_connections you should omit it from the query completely.
SELECT m.title, s.date
FROM site_movies_seen s
INNER JOIN site_movies m ON s.object_id = m.id
GROUP BY m.id, s.date
ORDER BY s.date

Related

3 tables joins on One to many

Im having some troubles learning about joins, im working with 2 One-to-many relation ships:
In this case, i have novels with many chapters and many ratings
I need to get the novels information plus a count of chapters associated to each novel and an avarage of the ratings of each novel and im trying this:
SELECT n.id
, n.nvl_title
, COUNT(c.id) AS nvl_chapters
, AVG(nr.rate_value) as nvl_rating
, MAX(c.createdAt) AS nvl_last_update
FROM novels n
left
JOIN novels_ratings nr
ON nr.novel_id = n.id
left
JOIN chapters c
ON c.nvl_id = n.id
AND c.chp_status = 'Active'
WHERE n.nvl_status IN ("Active", "Finished")
GROUP
BY n.id;
Working only with the chapters the query seems to work very fine but if I add the line "left JOIN novels_ratings nr ON nr.novel_id = n.id" the chapters count increment to many ratings the novel have.
For example: A novel with 2 chapters and 2 rating returns 4 chapters in total.
Any help will be fully apreciated.
If there is something I miss to explain, please, let me know and i will try to clarify.
I'veen working with some ugly querys that do the job but as soon as the chapters table begin to have MANY registers I have been forced to learn more optical querys
EDIT
I have create a small database, enough to make some tests on the query:
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
CREATE TABLE `chapters` (
`id` int(11) NOT NULL,
`nvl_id` int(20) DEFAULT NULL,
`chp_title` varchar(250) DEFAULT NULL,
`chp_status` varchar(8) NOT NULL DEFAULT 'Active',
`createdAt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `chapters` (`id`, `nvl_id`, `chp_title`, `chp_status`, `createdAt`) VALUES
(1, 1, 'generic chapter 1', 'Active', '0000-00-00 00:00:00'),
(2, 1, 'generic chapter 2', 'Active', '0000-00-00 00:00:00');
CREATE TABLE `novels` (
`id` int(20) NOT NULL,
`nvl_title` varchar(250) DEFAULT NULL,
`nvl_status` varchar(8) NOT NULL DEFAULT 'Active'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `novels` (`id`, `nvl_title`, `nvl_status`) VALUES
(1, 'generic novel', 'Active');
CREATE TABLE `novels_ratings` (
`id` int(20) NOT NULL,
`novel_id` int(20) DEFAULT NULL,
`rate_value` int(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `novels_ratings` (`id`, `novel_id`, `rate_value`) VALUES
(1, 1, 3),
(2, 1, 4);
ALTER TABLE `chapters`
ADD PRIMARY KEY (`id`);
ALTER TABLE `novels`
ADD PRIMARY KEY (`id`);
ALTER TABLE `novels_ratings`
ADD PRIMARY KEY (`id`);
ALTER TABLE `chapters`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
ALTER TABLE `novels`
MODIFY `id` int(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
ALTER TABLE `novels_ratings`
MODIFY `id` int(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
COMMIT;
Thank you very much!
I think the simplest way to do this is here:
SELECT n.id, n.nvl_title,
COUNT(c.id) AS nvl_chapters,
(select AVG(nr.rate_value) from novels_ratings nr where nr.novel_id = n.id) as nvl_rating,
MAX(c.createdAt) AS nvl_last_update
FROM novels n
left JOIN chapters c ON c.nvl_id = n.id AND c.chp_status = 'Active'
WHERE n.nvl_status IN ("Active", "Finished")
GROUP BY n.id;
Very straightforward, and it should perform well too.
This is a complete solution (finally). Since MySQL does not implement FULL JOIN the solution uses a LEFT JOIN paired with a RIGHT JOIN instead.
You can do:
with
r as (
select n.id, avg(nr.rate_value) as nvl_rating
from novels n
join novels_ratings nr on nr.novel_id = n.id
group by n.id
),
c as (
select n.id, count(c.id) as nvl_chapters, max(c.createdAt) as nvl_last_update
from novels n
join chapters c on c.nvl_id = n.id and c.chp_status = 'Active'
group by n.id
)
select r.id, r.nvl_rating, c.*
from r
left join c on c.id = r.id
UNION ALL
select c.id, r.nvl_rating, c.*
from r
right join c on c.id = r.id
where r.id is null

get data and count from table with join from two different tables

I have three tables activity_log, user, staff. I have to select data from activity_log to identify which user has done which activity.
This is structure of activity_log table
CREATE TABLE `activity_log` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`os` varchar(20) NOT NULL,
`api` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Dumping data for table activity_log
INSERT INTO `activity_log` (`id`, `user_id`, `os`, `api`) VALUES
(1, 1, 'web', 'user/login'),
(2, 2, 'web', 'user/report'),
(3, 1, 'android', 'user/login'),
(4, 2, 'ios', 'user/data'),
(5, 3, 'android', 'user/category'),
(6, 3, 'web', 'user/result'),
(7, 3, 'ios', 'user/send_sms');
This is structure of user table
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Dumping data for table user
INSERT INTO `user` (`id`, `first_name`, `last_name`) VALUES
(1, 'Yogesh', 'Kale'),
(2, 'Sunit', 'Desai'),
(3, 'Paresh', 'Godambe');
This is my staff table
CREATE TABLE `staff` (
`id` int(11) NOT NULL,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Dumping data for table staff
INSERT INTO `staff` (`id`, `first_name`, `last_name`) VALUES
(1, 'abcd', 'asas'),
(2, 'ajay', 'shinde'),
(3, 'kapil', 'parab');
But I have to join activity log on one condition. That condition is based on os column in activity_log table. That condition is if os column contain value as web then I have to join user_id of activity_log with id column of staff table and if os column contain value as ios or android then I have to join user_id of activity_log with id column of user table.
I need two different queries one for getting data with columns id and api from activity_log, first_name, last_name from either staff or user and another for getting total count for same above condition. I have given my table schema for reference.
I have tried following query for getting data
SELECT
al.id as id,
CONCAT(u.first_name, ' ', u.last_name) as user_name,
al.api
FROM
activity_log al
JOIN
user u
ON
u.id = al.user_id
WHERE
al.os IN('android','os')
UNION ALL
SELECT
al.id as id,
CONCAT(st.first_name, ' ', st.last_name) as user_name,
al.api
FROM
activity_log al
JOIN
staff st
ON
st.id = al.user_id
WHERE
al.os = 'web'
This above query returns me right data. But I dont know how to get count with above condition. Thats where I stuck in this. If possible please give me alternate queries for getting data and count.
Please help me in this. I spent whole day to figure out this. Thanks in advance
You can try using UNION ALL to get the required data.
Query 1:
select al.id, al.api,s.first_name, s.last_name from activity_log al inner join staff s on al.user_id=s.id where al.os='web'
UNION ALL
select al.id, al.api,u.first_name, u.last_name from activity_log al inner join user u on al.user_id=u.id where al.os!='web'
Query 2:
select
(select count(*) from activity_log al, staff s where al.user_id=s.id and al.os='web') as webcount,
(select count(*) from activity_log al, user u where al.user_id=u.id and al.os!='web') as othercount
I hope this gives you a direction for your question.
Try with
SELECT ...,count(*) FROM table1
INNER JOIN table2 ON ... WHERE ...

MySQL join three tables, sum of item join to main table

I have three MySQL tables:
For example
A Table is menu ID, name
B table is customer_order ID, order_date
C table is order_item ID, menu_item_id, customer_order_id, order_quantity
I try to output name, sum(order_quantity) in this month
Currently i have two separate query which working ok, but the second query is inside of foreach loop, which seem not so good.
First query which output all the menu items:
$results = $wpdb->get_results( "SELECT * FROM menu WHERE post_id = $pid ORDER BY sort_order ");
Second query will output total of each item sold on each month:
$total = $wpdb->get_col( "SELECT SUM(oi.order_item_quantity)
from order_item as oi
INNER JOIN customer_order as ho ON ho.ID = oi.order_id
WHERE oi.order_item_id = $subC->ID AND YEAR(ho.order_date) = $current_year AND MONTH(ho.order_date) = $current_month ");
I try to merge the two queries into one query, which has taken me whole day but still not able to solve it, can anyone give me some help please.
update
thanks Rene.
Select m.name, m.name as name, sum(oi.order_item_quantity) as sold_monthly from menu as m left join order_item as oi on oi.order_item_id = m.ID left join cusomter_order as co on co.ID = oi.order_id where m.post_id = 110 group by m.ID, m.name
this will output
name sold_monthly
Sushi Lunch Special NULL
Sushi Lunch 19
Sashimi Lunch 61
jason NULL
egg roll NULL
if i add YEAR(co.order_date) = 2016 AND MONTH(co.order_date) = 9
which i only get
name sold_monthly
Sushi Lunch 7
Sashimi Lunch 14
how can i keep sushi lunch special, jason, egg roll, the null item, when i add the YEAR(co.order_date) = 2016 AND MONTH(co.order_date) = 9.
here i try
(year(co.order_date) = 2016 and month(co.order_date) = 10) or sold_monthly is null
which give me a query error
update
thanks Rene again
it's working now
(year(co.order_date) = 2016 and month(co.order_date) = 10) or co.order_date is null
finally solve it, upper have little bug, when i change business_id which may not catch the result i want, so i am add a subquery to it.
Select m.*, p.sold_monthly from menu as m left join ( SELECT SUM(oi.order_item_quantity) as sold_monthly, oi.order_item_id as ID, oi.order_item_name from order_item as oi LEFT JOIN cusomter_order as ho ON ho.ID = oi.order_id WHERE ho.business_id = $pid AND (year(ho.order_date) = $current_year and month(ho.order_date) = $current_month) OR ho.order_date is NULL GROUP by oi.order_item_id )p on p.ID = m.ID where m.post_id = $pid
So you're trying to get a list per post_id limited by the selected month.
The following query will yield that for the following sample data.
SELECT m.ID as ID, m.Name as Name, SUM(oi.order_quantity) as Quantity
FROM menu as m
LEFT JOIN order_item as oi ON oi.menu_item_id = m.ID
LEFT JOIN customer_order as co ON co.ID = oi.customer_order_id
WHERE m.post_id = 0 AND YEAR(co.order_date) = 2016 AND MONTH(co.order_date) = 9 OR co.order_date is NULL
GROUP BY m.ID,m.Name,m.sort_order
ORDER BY m.sort_order
Sample Data
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
DROP TABLE IF EXISTS `customer_order`;
CREATE TABLE `customer_order` (
`ID` int(11) NOT NULL,
`order_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_german2_ci;
TRUNCATE TABLE `customer_order`;
INSERT INTO `customer_order` (`ID`, `order_date`) VALUES
(1, '2016-09-06 00:00:00'),
(2, '2016-09-13 00:00:00'),
(3, '2016-08-09 00:00:00'),
(4, '2016-09-19 00:00:00');
DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu` (
`ID` int(11) NOT NULL,
`sort_order` int(11) NOT NULL,
`post_id` int(11) NOT NULL,
`Name` varchar(20) COLLATE utf8_german2_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_german2_ci;
TRUNCATE TABLE `menu`;
INSERT INTO `menu` (`ID`, `sort_order`, `post_id`, `Name`) VALUES
(2, 0, 0, 'Test 1'),
(4, 1, 0, 'Test 2'),
(5, 2, 0, 'Test 3');
DROP TABLE IF EXISTS `order_item`;
CREATE TABLE `order_item` (
`ID` int(11) NOT NULL,
`menu_item_id` int(11) NOT NULL,
`customer_order_id` int(11) NOT NULL,
`order_quantity` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_german2_ci;
TRUNCATE TABLE `order_item`;
INSERT INTO `order_item` (`ID`, `menu_item_id`, `customer_order_id`, `order_quantity`) VALUES
(1, 2, 1, 1),
(2, 2, 2, 3),
(3, 4, 1, 1),
(4, 4, 2, 4),
(5, 2, 3, 3),
(6, 4, 3, 1),
(7, 2, 4, 4);
ALTER TABLE `customer_order`
ADD PRIMARY KEY (`ID`);
ALTER TABLE `menu`
ADD PRIMARY KEY (`ID`),
ADD KEY `idx_pid` (`post_id`);
ALTER TABLE `order_item`
ADD PRIMARY KEY (`ID`),
ADD KEY `idx_coid` (`customer_order_id`),
ADD KEY `idx_miid` (`menu_item_id`);
ALTER TABLE `customer_order`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
ALTER TABLE `menu`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
ALTER TABLE `order_item`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
ALTER TABLE `order_item`
ADD CONSTRAINT `CostomerOrderConstrain` FOREIGN KEY (`customer_order_id`) REFERENCES `customer_order` (`ID`),
ADD CONSTRAINT `MenuItemConstrain` FOREIGN KEY (`menu_item_id`) REFERENCES `menu` (`ID`);
Good luck integrating the query, let me know if it worked.
Update: Updated sample data to reproduce the actual problem. Updated the Solution Query.

how to do group by and order by in one query?

I have two table one is 'tb_student' and other is 'tb_fees'
create query for 'tb_student'
CREATE TABLE `tb_student` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`class` varchar(255) NOT NULL,
`created_on` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
)
create query for 'tb_fees'
CREATE TABLE `tb_fees` (
`id` int(11) NOT NULL auto_increment,
`email` varchar(255) NOT NULL,
`amount` varchar(255) NOT NULL,
`created_on` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
)
In first table i am storing the student details and in other table storing the fees details
I want to select student details from 'tb_student' and last add fee from 'tb_fees' only for those student which are in class 6
so i tried this
SELECT *
FROM tb_student s INNER JOIN
tb_fees f on
s.email =f.email
WHERE s.class = 6 GROUP BY s.email ORDER BY f.created_on DESC
This will give result only the first created how to get last created values
fees table
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (5,'ram#gmail.com','5000','2013-05-01 14:20:15');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (6,'Sam#gmail.com','5000','2013-05-02 14:20:23');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (7,'jak#gmail.com','5000','2013-05-03 14:20:30');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (8,'Sam#gmail.com','5000','2013-05-29 14:20:35');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (9,'ram#gmail.com','5000','2013-05-30 14:20:39');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (10,'jak#gmail.com','5000','2013-05-30 14:36:13');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (11,'rose#gmail.com','5000','2013-05-30 14:36:15');
insert into `tb_fees`(`id`,`email`,`amount`,`created_on`) values (12,'nim#gmail.com','5000','2013-05-30 14:36:15');
Student table values
insert into `tb_student`(`id`,`name`,`email`,`class`,`created_on`) values (5,'Ram','ram#gmail.com','6','2013-04-30 14:00:56');
insert into `tb_student`(`id`,`name`,`email`,`class`,`created_on`) values (6,'Sam','Sam#gmail.com','6','2013-03-30 14:01:30');
insert into `tb_student`(`id`,`name`,`email`,`class`,`created_on`) values (7,'Nimmy','nim#gmail.com','7','2013-04-30 13:59:59');
insert into `tb_student`(`id`,`name`,`email`,`class`,`created_on`) values (8,'jak','jak#gmail.com','6','2013-03-30 14:07:32');
insert into `tb_student`(`id`,`name`,`email`,`class`,`created_on`) values (9,'rose','rose#gmail.com','5','2013-04-30 14:07:51');
Thank you
To get the latest fees something like this:-
SELECT s.* , f.*
FROM tb_student s
INNER JOIN
(SELECT email, MAX(created_on) AS created_on
FROM tb_fees
GROUP BY email) Sub1
ON s.email = sub1.email
INNER JOIN tb_fees f
ON s.email = f.email AND Sub1.created_on = f.created_on
WHERE s.class = 6
By the way, you probably want indexes on the email fields (or better, use the tb_student id field on the tb_fees table instead of the email field and index it)
Use MAX group function
SELECT s.*, f.amount,MAX(f.created_on)
FROM tb_student s
INNER JOIN
tb_fees f
ON
s.email =f.email
WHERE s.class = 6
GROUP BY s.email

How implementation my wants with MySQL JOIN

_
Hello everyone!
I have table
CREATE TABLE `labels` (
`id` INT NULL AUTO_INCREMENT DEFAULT NULL,
`name` VARCHAR(250) NULL DEFAULT NULL,
`score` INT NULL DEFAULT NULL,
`before_score` INT NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
And I Have This Table
CREATE TABLE `scores` (
`id` INT NULL AUTO_INCREMENT DEFAULT NULL,
`name_id` INT NULL DEFAULT NULL,
`score` INT NULL DEFAULT NULL,
`date` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`)
);
And i want have result where labels.score - have value last scores.score sorted by scores.date and labels.before_score where have value penultimate scores.score sorted by scores.date. Can I do This Only on Mysql slq and how?
Thanks.
ADD
For example i have this data on first table:
INSERT INTO `labels` (id, name, score, before_score) VALUES (1, 'John', 200, 123);
INSERT INTO `labels` (id, name, score, before_score) VALUES (2, 'Eddie', 2000, 2000);
INSERT INTO `labels` (id, name, score, before_score) VALUES (3, 'Bob', 400, 3101);
And second table
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('1','1','12','2013-07-10');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('2','2','2000','2013-05-04');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('3','3','654','2012-09-12');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('4','1','123','2013-12-17');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('5','1','200','2014-04-25');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('6','3','3101','2013-12-02');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('6','2','2000','2015-12-02');
INSERT INTO `scores` (`id`,`name_id`,`score`,`date`) VALUES ('6','3','400','2013-12-02');
If I understand correctly, you need the last two scores for each name_id.
I would tackle this with temporary tables:
Step 1. Last score:
create temporary table temp_score1
select name_id, max(`date`) as lastDate
from scores
group by name_id;
-- Add the appropriate indexes
alter table temp_score1
add unique index idx_name_id(name_id),
add index idx_lastDate(lastDate);
Step 2. Penultimate score. The idea is exactly the same, but using temp_score1 to filter the data:
create temporary table temp_score2
select s.name_id, max(`date`) as penultimateDate
from scores as s
inner join temp_score1 as t on s.nameId = t.nameId
where s.`date` < t.lastDate
group by name_id;
-- Add the appropriate indexes
alter table temp_score2
add unique index idx_name_id(name_id),
add index idx_penultimateDate(penultimateDate);
Step 3. Put it all together.
select
l.id, l.name,
s1.lastScore, s2.penultimateScore
from
`labels` as l
left join temp_score1 as s1 on l.id = s1.name_id
left join temp_score2 as s2 on l.id = s2.name_id
You can put this three steps inside a stored procedure.
Hope this helps you.