I'm trying to make a SQL query that will search for user id and populate the query with the username.
These are my tables:
Table Names: 'users' and 'schedule'
This is how I want it to look like, where 'schedule' table now shows the username instead of the user's ID
This is the query you are looking for:
SELECT s.REFID, s.jobnum, s.customer, u1.username AS engineer, u2.username AS sales
FROM schedule s, users u1, users u2
WHERE s.engineer=u1.id
AND s.sales=u2.id
You need to reference the users table two separate times, since you are checking in one sub-query for the engineer's username, and then checking in a separate sub-query for the salesperson's username.
Here is a link to an SQLFiddle that shows the result of the query's execution. It matches up with what you were looking for. I hope this helps.
Following Query will give you the expected result:
SELECT
s.refid as refid,
s.jobnum as jobnum,
s.customer as customer,
u_engg.username as engineer,
u_sales.username as sales
FROM
user u_engg join schedule s on u.id = s.engineer join
user u_sale on u_sale.id = s.sales
SELECT s.refid, s.jobnum, s.customer, u.username engineer, u.username sales
FROM schedule s
LEFT OUTER JOIN users u
ON s.engineer = u.id AND s.sales = u.id
It looks like you need to reference the users table two times. One JOIN to get the engineer username, and a second JOIN to get the sales username.
Something like this:
-- return all rows from schedule, and lookup of username where available
SELECT s.REFID
, s.jobnum
, s.customer
, e.username AS engineer
, a.username AS sales
FROM schedule s
LEFT
JOIN users e
ON e.id = s.engineer
LEFT
JOIN users a
ON a.id = s.sales
Using a LEFT [OUTER] JOIN ensures that the rows from schedule will be returned when there isn't a matching row in the users table. For example, if you had a NULL in the sales column of a row in schedule, there wouldn't be a matching row in the users table. With an [INNER] JOIN, the row from schedule would not be returned. But the query above does return the row, but with a NULL for the username when matching rows are not found.
If the engineer and sales columns are defined as NOT NULL, and foreign keys are defined and enforced, then the LEFT keyword can be omitted from the query above. In the more general case, where foreign keys are not enforced (e.g. MyISAM) or not defined, or the columns are nullable, we'd generally want the LEFT keywords.
UPDATE
Removing the LEFT keywords from the query will produce a query equivalent to that in the answer from Alvin Lee, which implements INNER JOIN operations.
The query from Alvin Lee will EXCLUDE rows from schedule that have a value in the engineer or sales column that is NULL, or has a value that does not match a value found in the id column of the users table.
To identify if any rows in the schedule table are not being returned by the query using an INNER JOIN, you can run a query that does an anti-join pattern.
-- find rows in schedule that don't have matching row in users
SELECT s.REFID
, s.jobnum
, s.customer
, s.engineer
, s.sales
FROM schedule s
LEFT
JOIN users e
ON e.id = s.engineer
LEFT
JOIN users a
ON a.id = s.sales
WHERE a.id IS NULL
OR e.id IS NULL
try this:
select sc.REFID, sc.jobnum, sc.customer, us.username as engineer, us.username as sales
from schedules as sc
left join users as us on sc.engineer = us.ID and sc.sales = us.ID
Related
I want to get customer data from all the businesses with more than 1 user.
For this I think I need a subquery to count more than 1 user and then the outer query to give me their emails.
I have tried subqueries in the WHERE and HAVING clause
SELECT u.mail
FROM users u
WHERE count IN (
SELECT count (u.id_business)
FROM businesses b
INNER JOIN users u ON b.id = u.id_business
GROUP BY b.id, u.id_business
HAVING COUNT (u.id_business) >= 2
)
I believe that you do not need a subquery, everything can be achieved in a joined aggregate query with a HAVING clause, like :
SELECT u.mail
FROM users u
INNER JOIN businesses b on b.id = u.id_business
GROUP BY u.id, u.email
HAVING COUNT (*) >= 2
NB : in case several users may have the same email, I have added the primary key of users to the GROUP BY clause (I assumed that the pk is called id) : you may remove this if email is a unique field in users.
how to perform sql count(*) query on results of another query performing multiple results ?
I've 3 tables :--
user_subscribe table where I've 'user_id' and other columns.
user table where we have 'user_id' & 'country_id' columns where user_id is being linked with user_subscribe table and country_id is being linked with 'country' table.
country table having 'country_id' column.
I need to get total count of user_subscribe based on users (user_id) who belongs to same country.
A Help is highly appreciated as I'm being stuck on this problem from last 7 days.
SELECT COUNT(US.user_id) as country_user_subscribed
FROM user_subscribe as US
LEFT JOIN users as U ON user.id=US.user_id
LEFT JOIN countries as C on C.id=U.country_id
GROUP BY C.country_id
Try This Solution :
SELECT C.CountryName,Count(u.UserId) AS UserCount FROM User_Subscribe AS us
LEFT JOIN User AS u ON us.UserId = u.UserId
LEFT JOIN Country AS c ON u.CountryId = c.CountryId
WHERE c.CountryId = 3
GROUP BY c.CountryName
So, I am trying to select customers that are completely inactive with MySQL join. I have the following statement that selects all the customers with an active service order.
SELECT DISTINCT u.* FROM users u INNER JOIN orders o ON o.assigned=u.id AND o.status!=0
This works just fine. But now I am trying to select customers who previously had an order but the order became deactivated (o.status would equate to the value 0). I have the following statement (which is close) but it is returning customers who still have an active order, but have another order which was deactivated.
SELECT DISTINCT u.* FROM users u INNER JOIN orders o ON o.assigned=u.id AND o.status!=1
So in layman term, basically a customer can have multiple service orders. Every service being independent from one another, I want to select the customers who are COMPLETELY deactivated. For example:
Susan has 2 service orders, 1 which is activated and the other deactivated. Right now, Susan is being populated in the list of users who are deactivated and that is incorrect. Only the customers whose orders are completely deactivated.
Thank you!
SELECT u.*
FROM users u
LEFT
JOIN orders o
ON o.assigned=u.id
AND o.status!=0
WHERE o.assigned IS NULL;
or something like that
In order to account for this scenario, you need to do a WHERE clause that would include the opposite SELECT statement.
For example:
select distinct u.* from users u inner join orders o
on o.assigned=u.id and o.status!=1
where u.id != (select distinct s.id from users s inner join orders r
on r.assigned = s.id and r.status!=0 where s.id == u.id)
Okay, so I am trying to perform a query that has 4 tables,
users, events, event_roles, user_event_role.
The users can fill multiple roles. What i am trying to do is get a result that looks more like this:
User, event, Role(s)
So if user 'Bill' is associated with event 'Meeting' and 'Bill' Fills multiple roles instead of getting a result like this:
user event role
--------------------------
bill Meeting admin
bill Meeting director
how would I get my result to be like this
user event role role
----------------------------------
bill Meeting admin director
Here is a query that I'm trying to build off of.
Select *
FROM `users` u
LEFT JOIN `event_role` er ON u.user_id = er.user_id
LEFT JOIN `events` e ON er.event_id = e.event_id
The result you seek is not possible.
However there is something close:
SELECT
user,
event,
group_concat(role SEPARATOR ',') as roles
FROM
`users` u
LEFT JOIN `event_role` er
ON u.user_id = er.user_id
LEFT JOIN `events` e
ON er.event_id = e.event_id
GROUP BY u.user_id
which would yield:
user event roles
----------------------
bill Meeting admin,director
In either case you would need to adjust your logic to parse it correctly.
You cannot get such result, because you don't know how many roles there might be (i.e. columns count), but you can use GROUP_CONCAT that way:
SELECT *,
GROUP_CONCAT(event_roles.role SEPARATOR ',') as roles
FROM users
LEFT JOIN event_role USING(user_id)
LEFT JOIN events USING(user_id)
GROUP BY user_id
Using this query you will get all roles concatonated with ,. But be aware of limitation of GROUP_CONCAT, the default value is set to 1024 characters which might not be enough (see my.cnf).
Use Group_concat (http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html) like this.
To show that quickly, I'm using a database from the excellent MySQL intro book by Ben Forta (http://www.forta.com/books/0672327120/), no affiliation.
SELECT v.vend_id, GROUP_CONCAT(p.prod_id)
FROM products p
JOIN vendors v ON v.vend_id= p.vend_id
JOIN orderitems oi ON oi.prod_id = p.prod_id
GROUP BY v.vend_id;
I have a table for referred users (contains an email address and date columns) and a table for users.
I run to get the top referers:
SELECT count(r.Email) as count, r.Email
FROM refs r
WHERE r.referredOn > '2011-12-13'
GROUP BY email
ORDER BY count DESC
But I want to join this with the users table so it displays with other data in the user table, I thought a join would work. Left join becuase emails may be entered incorrectly, some people put first name etc under refs.Email
SELECT count(r.Email) as count, r.Email, u.*
FROM refs r LEFT JOIN users u ON u.email_primary = r.Email
WHERE r.referredOn > '2011-12-13'
GROUP BY email
ORDER BY count DESC
With the above query the count is incorrect, but I don't know why.
Try this one:
SELECT count(r.Email) as count, r.Email
FROM refs r
INNER JOIN users u ON u.email_primary = r.Email
WHERE r.referredOn > '2011-12-13'
GROUP BY email
ORDER BY count DESC
if your adding new column from users u you also need to add it on your group by clause.
Regards
Unfortunately, a LEFT JOIN wont help you here; what this type of join says is give me all the rows in users that match my email, as well as all the rows that have no match on email. If the email doesn't match, then they wont come back as you want.
So you can't use a the left join condition here the way you want.
If you enforced the fact that they had to enter an email everytime, and it was a valid email etc, then you could use an INNER JOIN.
JOINs are usually used to follow referential integrity. So, for example, I have a user with an id in one table, and another table with the column userid - there is a strong relationship between the two tables I can join on.
Jeft Atwood has a good explantion of how joins work.
SEE if this will help you:
SELECT e.count, e.email, u.col1, u.col2 -- etc
FROM (
SELECT count(r.Email) as count, r.Email
FROM refs r
WHERE r.referredOn > '2011-12-13'
GROUP BY email
) e
INNER JOIN
users u ON u.email_primary = e.Email
Instead of a direct join, you could TRY to use your counting query as a subquery-table type..
I wrote this query
SELECT *, count(r.Email) as count FROM refs r
LEFT OUTER JOIN users u ON r.email = u.email_primary
WHERE u.uid IS NOT NULL
GROUP BY u.uid
ORDER BY count DESC
Which showed me that the reason the count was wrong was because some of the email addresses are used twice in the users table (users sharing 'family' email address), this doubled my count, the above query shows each separate user account.