I have a UNION statement to combine scores for students from two different tables (MySQL 5.6). It is returning inconsistent results. When I run each statement independently, they generate the right results for all students. When I combine them with the UNION, it is correct for all but one student.
Even stranger, if I remove any one of the items being added from the first query, it sums correctly for ALL records.
For instance, removing sum(ifnull(owl_tracker.pre_req_points,0)) or sum(ifnull(owl_tracker.bonus_points,0)) from the query causes it to return correct results for all students.
select first_name, last_name, location, sum(total_points) as total_points from (
select first_name, last_name, location, (
sum(ifnull(owl_tracker.pre_req_points,0)) +
sum(ifnull(owl_tracker.bonus_points,0)) +
sum(ifnull(owl_tracker.a_points,0))) AS total_points
from products, students_products, students
Fiddle here: http://sqlfiddle.com/#!9/7ea891/1
Student A works correctly but Student B does not.
You need to use union all, try below query and it's better if you use explicit join
http://sqlfiddle.com/#!9/7ea891/7
select first_name, last_name, location, sum(total_points)
from
(
select first_name, last_name, location, (
sum(ifnull(owl_tracker.pre_req_points,0)) +
sum(ifnull(owl_tracker.bonus_points,0)) +
sum(ifnull(owl_tracker.a_points,0))) AS total_points
from products left join students_products on products.product_id = students_products.product_id
left join students on students_products.student_id = students.unique_id
left join owl_tracker on students.unique_id = owl_tracker.student_id
where products.product_type in ('Group_Course','Full_Course') and products.test_date_id = '19' and unique_id in ('4833' ,'4956')
group by first_name, last_name, location
union all
select first_name, last_name, location,
sum(ifnull(owl.points,0)) AS total_points
from products left join students_products on
products.product_id = students_products.product_id
left join students on students_products.student_id = students.unique_id
left join owl on students.unique_id = owl.student_id
where products.product_type In ('Group_Course' ,'Full_Course') and
products.test_date_id = '19' and
unique_id in( '4833' , '4956')
group by first_name, last_name, location) t_union
group by first_name, last_name, location
order by location, last_name
By default, UNION is UNION DISTINCT, which means that any duplicated row will be filtered out in the subquery. Change that to UNION ALL. See What is the difference between UNION and UNION ALL?
Related
I have used UNION for 2 separate Mysql query, The query is as below.
select country,u_id from
(SELECT regionShortName as country , GROUP_CONCAT( urls_regions.u_id ) AS
u_id
FROM urls_regions
where LENGTH(regionShortName )<=2
GROUP by regionShortName)
UNION
(SELECT countries.name as country,
GROUP_CONCAT( urls_regions.u_id ) AS u_id
FROM `countries` countries
inner join regions on countries.regions_id = regions.id
INNER JOIN urls_regions ON regions.region = urls_regions.regionShortName
GROUP by countries.name, country)
The above query has given me the results as below,
I am not able to achieve as below,
Now I would like know how to group by the "country" by concat(merge or join) "u_id"
Is my query implemented is right approach or is there any other approach to achieve this.
Using below query I am able to get what I am expecting,
select tb.country, GROUP_CONCAT(tb.u_id, ',') from
((SELECT regionShortName as country , GROUP_CONCAT( urls_regions.u_id ) AS
u_id
FROM urls_regions
where LENGTH(regionShortName )<=2
GROUP by regionShortName)
union
(SELECT countries.name as country,
GROUP_CONCAT(urls_regions.u_id ) AS u_id
FROM `countries` countries
inner join regions on countries.regions_id = regions.id
INNER JOIN urls_regions ON regions.region = urls_regions.regionShortName
GROUP by countries.name, country)) tb group by tb.country
I have done 2 things
In my first line of query I have added GROUP_CONCAT(tb.u_id, ',')
In the last line added group by tb.country
How can I summarize results of two queries below?
select firstname, surname, COUNT(*) as Built
from orders
join users on orders.builder = users.id
where bStop > 1461496211 and bStop < 1461582649
group by users.id;
select firstname, surname, COUNT(*) as Built
from production_points
join users on production_points.rewarded = users.id
where Date(datetime) = '2016-04-25'
group by users.id
Same user can be in both tables, so i want to sum his results, don't want two separate lines i.e. first one showing 4 and second one 6. Just total 10
You can use Union.
If this is mysql you can see its syntax here: http://dev.mysql.com/doc/refman/5.7/en/union.html
It is similar in the other DB vendors.
Can you maybe get the result of each and assign them to different variables.
And sum up the variables.
After research as advised by you guys, here is the solution:
select uid, firstname, surname, Count(*) as Built from (
select users.id as uid, firstname, surname from orders join users on orders.builder = users.id where bStop > 1461542400 and bStop < 1461592622
union all
select users.id as uid, firstname, surname from production_points join users on production_points.rewarded = users.id where Date(datetime) ='2016-04-25'
) performance group by uid;
I am trying to combine 2 queries, one counting the users in each country and the other counting the users in each country using public phones and merging the columns together. However, I keep getting an error near the inner join code region. I am using HeidiSQL so that is the only error message I get. Each nested query runs perfectly on its own. Anyone knows what's wrong?
SELECT
AllUsers.country,
AllUsers.TotalUsers,
PublicUsers.PublicPhoneUsers
FROM
(SELECT
country,
count(country) As "TotalUsers"
FROM
userlist
GROUP BY
country) AS "AllUsers"
INNER JOIN
(SELECT
country,
count(country) As "PublicPhoneUsers"
FROM
userlist
WHERE
phone_public = 1
GROUP BY
country) AS "PublicUsers"
ON
AllUsers.country = PublicUsers.country;
Please remove the double quotation marks from both your column and table aliases:
SELECT AllUsers.country, AllUsers.TotalUsers, PublicUsers.PublicPhoneUsers
FROM
(
SELECT country, COUNT(country) As TotalUsers
FROM userlist
GROUP BY country
) AS AllUsers
INNER JOIN
(
SELECT country, COUNT(country) As PublicPhoneUsers
FROM userlist
WHERE phone_public = 1
GROUP BY country
) AS PublicUsers
ON AllUsers.country = PublicUsers.country
I'm a rookie and am trying to get the difference between two query outputs. Each query creates a list. Query A list > Query B list. Also, query B output is a subset of query A.
Query A:
SELECT first_name, last_name
FROM users
WHERE rating <> '6';
Query B:
SELECT DISTINCT first_name, last_name
FROM users
JOIN mp_positions
ON users.id=mp_positions.user_id
JOIN mps
ON mps.id=mp_positions.mp_id
WHERE mps.status_id = '5';
Any help would be appreciated.
I'm not entirely sure of the structure of your tables although you'll probably want to try something like this:
SELECT first_name, last_name
FROM users
WHERE rating <> '6'
AND users.id
NOT IN (SELECT DISTINCT first_name, last_name
FROM users
JOIN mp_positions
ON users.id=mp_positions.user_id
JOIN mps ON mps.id=mp_positions.mp_id
WHERE mps.status_id = '5'
);
Banging my head on this one and not sure how to resolve. I need to return 1 row per teamcode from the teams tables (distinct values) that includes user information.
Table users can have multiple values bases on the team code but I need it to only return 1 (any one, it doesn't matter which). I've tried:
SELECT a.teamcode, a.area, c.uniqid, c.fullname, c.email
FROM teams a
LEFT JOIN
(SELECT uniqid, CONCAT(first_name, ' ', last_name ) AS fullname, email, teamcode from users LIMIT 1) c
on a.teamcode = c.teamcode
WHERE a.area= 'ZF15'
Ive also tried max:
SELECT a.teamcode, a.area, c.uniqid, c.fullname, c.email
FROM teams a
LEFT JOIN
(SELECT max(uniqid) as uniqid, CONCAT(first_name, ' ', last_name ) AS fullname, email, teamcode from users) c
on a.teamcode = c.teamcode
WHERE a.area= 'ZF15'
But the sub query returns null values from the users table. However, when I remove limit and max, I get the users table values but I get multiple rows per team code. Any ideas?
I think this should work, joining users on itself on the max(uniqid) per team:
SELECT a.teamcode, a.area,
c.uniqid, CONCAT(c.first_name, ' ', c.last_name ) AS fullname, c.email
FROM teams a
LEFT JOIN (
SELECT MAX(uniqid) maxuniqid, teamcode
FROM users
GROUP BY teamcode
) u on a.teamcode = u.teamcode
LEFT JOIN users c on c.teamcode = u.teamcode
AND c.uniqid = u.maxuniqid
WHERE a.area= 'ZF15'
This gets the max(uniqid) from the users table, grouped by the teamcode (1 for each team). Then joins back to the users table to get the name and email for that user.