Thus, the script displays the values, but duplicates them, many values with the same email and date. You need to get unique values, for example, there may be the same emails, but with a different date. But not the same emails with the same date.
DISTINCT after SELECT does not work, as well as applying it before each field.
group by and order by too, they cannot add more than two fields. When I accept group by email, it displays all the unique values, but does not display the values that are also needed when two identical emails, but different dates, it displays stupidly one email and that's it.
What to do help.
SELECT concat(last_name, ' ', first_name, ' ', middle_name) as 'ФИО',
email,
phone,
created_at,
total,
color
FROM user
INNER JOIN `user` ON `order`.user_id = `user`.id
INNER JOIN `color` ON `user`.color_id = `color`.id
You need to use the keyword DISTINCT after the SELECT.
Example:
SELECT DISTINCT concat(last_name, ' ', first_name, ' ', middle_name) as 'ФИО',
email,
phone,
created_at,
total,
color
FROM user
You have order the results by combing fields from the three tables:
SELECT concat(last_name, ' ', first_name, ' ', middle_name) as 'ФИО',
email,
phone,
created_at,
total,
color,
o.PRIMARY_KEY_HERE,
c.id
FROM user AS u
INNER JOIN `order` AS o ON o.user_id = u.id
INNER JOIN `color` AS c ON c.id = u.color_id
ORDER BY u.email, o.PRIMARY_KEY_HERE, c.id
Note
The query has been refactored to satisfy the ORDER BY clause.
Related
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?
have 3 following tables:
users (id, name)
projects (id, name)
user_to_project (user_id, project_id)
Every user can be assigned to more than one project and this is stored in the user_to_project table. I want to get a user name and all the projects he's assigned to in one field separated with commas. I tried something like this:
SELECT
users.id AS 'ID',
users.name AS 'Name',
(SELECT GROUP_CONCAT (projects.name SEPARATOR ', ')
FROM user_to_project
INNER JOIN projects ON (projects.id = user_to_project.project_id)
INNER JOIN users ON (users.id = user_to_project.user_id)) AS 'Projects'
FROM users
It gets me all assigned projects in every row which is not that I want. How to fix this?
You can do this with a subquery, but you want a correlation clause:
SELECT u.id, u.name,
(SELECT GROUP_CONCAT(p.name SEPARATOR ', ')
FROM user_to_project tup INNER JOIN
projects p
ON p.id = utp.project_id
WHERE u.id = utp.user_id
) as Projects
FROM users u;
Notes:
Use table aliases. They make a query easier to write and to read.
Don't use single quotes for column aliases. Only use single quotes for string and column names (and your column aliases don't require any escape character).
This is different from a version using INNER JOIN, because this will keep all users, even those with no projects.
I didn't see any reason for this correlated query, and you were missing a condition inside to relate it to the outer query. You also needed a group by clause.
This query should give you all the projects for each ID :
SELECT users.id, users.name ,
GROUP_CONCAT (projects.name SEPARATOR ', ')
FROM user_to_project
INNER JOIN projects ON (projects.id = user_to_project.project_id)
INNER JOIN users ON (users.id = user_to_project.user_id)
GROUP BY users.id,users.name
Note: To make your query work, all you need is to drop the users table from the inner query, and keep the condition.
I have two tables in MySQL.
First table is EMPLOYEES, it contain such columns as LASTNAME, NAME, MIDDLENAME, BIRHDATE and others about employees.
Second table is PROJECTS. It has among other things column STAFF.
STAFF has rows like
lastname1 name1, middlename1; lastname2 name2, middlename2.....
I need to get people from EMPLOYEES who are in the STAFF.
query
SELECT LASTNAME, NAME, MIDDENAME from EMPLOYEES where
CONCAT('%', LASTNAME, ' ', NAME, ' ',MIDDENAME, '%')
like (SELECT STAFF FROM PROJECTS)
doesn't work because LIKE must have one substring from 2nd query
and query
SELECT LASTNAME, NAME, MIDDENAME from EMPLOYEES where
CONCAT('%', LASTNAME, ' ', NAME, ' ',MIDDENAME, '%')
IN (SELECT STAFF FROM PROJECTS)
doesn't work too because for IN need full matching
any ideas?
That's what happens when you have delimited string like that in table which is against normalization. First consider normalizing your table. For now, you can perform a JOIN probably like below but if STAFF column has data in exact in format else matching will not occur.
SELECT e.LASTNAME, e.NAME, e.MIDDENAME
FROM EMPLOYEES e
JOIN PROJECTS p
ON CONCAT(e.LASTNAME, ' ', e.NAME, ' ', e.MIDDENAME) = p.STAFF;
You can as well use FIND_IN_SET() function like below but again consider changing your DB design first and Normalize your table(s)
SELECT LASTNAME,
NAME,
MIDDENAME
FROM (
SELECT LASTNAME, NAME,
MIDDENAME,
CONCAT(e.LASTNAME, ' ', e.NAME, ' ', e.MIDDENAME) as Full_Name
FROM EMPLOYEES) e
JOIN PROJECTS p
ON FIND_IN_SET(Full_Name, p.STAFF) > 0;
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.
i have an information table that has the following fields in it;
id, staffMember, lineManager, description
The staffMember and lineManager fields return integer values that correspond to the id of rows within a users table which has the following columns
id, firstname, surname
I can use the following query to return the info in my information table, substituting the staffMember value for a CONCAT of firstname and surname:
SELECT information.id,
CONCAT( users.firstname, ' ', users.surname ) AS staffMember,
information.lineManager,
LEFT(information.description,200) As description
FROM information
LEFT JOIN users
ON ( information.staffMember = users.id )
LIMIT 0 , 30"
But what i want to be able to do, is repeat the process that's working on the value of staffMember on lineManager as well in the same query (which i then pass as a json string) - however, i know i can't have two LEFT joins to the same table but equating different fields.
Any help would be gratefully received.
It sounds like you want this:
SELECT i.id,
CONCAT(u1.firstname, ' ', u1.surname) AS staffMember,
CONCAT(u2.firstname, ' ', u2.surname AS lineManager,
LEFT(i.description,200) As description
FROM information i
LEFT JOIN users u1
ON i.staffMember = u1.id
LEFT JOIN users u2
on i.lineManager = u2.id
LIMIT 0 , 30
You just perform a LEFT JOIN on the users table twice. Once you will join on the staffMember and the other time you will join on lineManager. By providing a different table alias to the table you can distinguish between the tables and the values.
Of if you want to be clearer:
SELECT i.id,
CONCAT(staff.firstname, ' ', staff.surname) AS staffMember,
CONCAT(manager.firstname, ' ', manager.surname AS lineManager,
LEFT(i.description,200) As description
FROM information i
LEFT JOIN users staff
ON i.staffMember = staff.id
LEFT JOIN users manager
on i.lineManager = manager.id
LIMIT 0 , 30
Something like this:
SELECT information.id FROM information
LEFT JOIN users u ON u.id = information.staffMember
LEFT JOIN users ul ON ul.id = information.lineManager
The letters/words after the table are completely made up by you. They are aliases for the table name that you make up on the fly.