Need Help writing a MySQL query - mysql

I have a database with customer information, orders, etc. I need to run a query that returns all customers who have not placed an order at all.
Relevant tables: login and orders
Relevant Columns: login.loginID, login.loginFirstName, login.loginLastName, login.loginEmailAddress AND orders.OrderuserID
So essentially - in psuedocode: compare table login, column loginID for matches in the orders table under orders.OrderUserID. If no match exists (as in no orders placed) then output the users First Name, Last Name and Email address.
I have been racking my brain but having some real issues with the language. I'm a big time N00B when it comes to SQL.

Basically it'll look like that:
SELECT l.login_id
FROM login l
LEFT JOIN orders o
ON l.login_id = o.login_id
WHERE o.login_id IS NULL
The key is using LEFT JOIN with WHERE ... IS NULL condition. In other words, you specifically look for the rows in login table that don't have any information 'extended' within orders table.
That's just a general description, but I hope it should be helpful in your process of constructing the big query specific to your case. )

select loginFirstName, loginLastName, loginEmailAddress
from login
where loginID not in
(select distinct OrderuserID from orders)
You can also do it with a left join:
select loginFirstName, loginLastName, loginEmailAddress
from login left join orders on loginID = OrderuserID
where OrderuserID is null
Not sure which will execute faster; give it a try. The first is easier to understand, IMHO.
EDIT: "select distinct" means "return me the set of unique values of the field". So, the subquery in the first SQL returns the set of users (their IDs) who do have orders. If a user has multiple orders, DISTINCT makes sure her ID is returned only once.

This should do it:
select *
from login l
left join orders o on l.loginId = o.OrderuserID
where o.OrderuserID is null

Try:
select login.loginFirstName, login.loginLastName, login.loginEmailAddress
FROM login
LEFT OUTER JOIN orders ON login.loginID = orders.OrderuserID
WHERE orders.OrderuserID IS NULL;
or something like that. I suspect the trick for a newer SQL user is the LEFT OUTER join. Without that specifier, a join will only return rows from the first table IF there are matches in the second. This way you get them all (and then filter out matches with the IS NULL phrase).

Though you should try first yourself and you could search on google first :):) .
Anyways you can use it in this way,
SELECT l.loginFirstName,l.loginLastName,
l.loginEmailAddress FROM login AS l LEFT JOIN orders as o
ON l.loginID = o.OrderuserID where OrderuserID is NULL

Related

learning mysql, JOIN query

i'm a beginner on MYSQL db and i'm trying to play around with the query and relations.
i have created 2 tables, one is 'users' which contain the field staff_ID and the other is 'reports' which also contain the table field staff_ID of the user submitting the reports.
on the relations (see picture) i have connect the 2 staff id field.
every user can submit more than one reports, so i'm try to query and get only the reports of one users(staff_ID).
I understood i have to use the JOIN keyword in order to obtain the data..
i tried the following query but it gave me all the result for all the users.
SELECT u.staff_ID
, u.Name
, r.id_report_show
, r.date_report
FROM users u
JOIN reports r
ON r.staff_ID = u.staff_ID
but I would like to have the report only of one specific user like staff_ID = 04033
probably i understood wrong how this query JOIN work, i'm looking for some help.
Thanks
You are almost there. Your join is perfect. You just need a where clause.
SELECT users.staff_ID, users.Name, reports.id_report_show, reports.date_report
FROM `users` INNER JOIN reports ON reports.staff_ID = users.staff_ID
where users.staff_ID = 04033
Or you can also mention it within on clauses:
SELECT users.staff_ID, users.Name, reports.id_report_show, reports.date_report
FROM `users` INNER JOIN reports
ON reports.staff_ID = users.staff_ID and users.staff_ID = 04033
Since it's inner join both the query will produce same output. But for left join those might produce different result. It's a good practice to use where clause instead of mentioning the condition in on clause.

MySQL Join statement to get data from two tables into a datagridview

I have two tables that I'm trying to join, 'holidays' and 'users'.
Users contains all my user info, the the column 'id' being primary and unique.
Holidays contains a column called 'userid', which corresponds to the id in the user table.
I'm struggling to get the join statement to work... what I'm looking for is the result of the select statement to give me the friendlyname (column 'fname' in user table) instead of giving me the value of userid.
Here's what I'm trying...
SELECT * FROM holidays JOIN users on users.id=holidays.userid WHERE holidays.status = 0
But i'm not getting a correct result - SQL executes without error, but my DGV is filled with tons of erroneous results.
Apologies If I have not used the correct terminology or whatever.
I'm new to the concept of joins.
Here is hopefully a better explanation of what I am after...
Thanks in advance.
You need to select the specific values you want from every table in the JOIN:
SELECT u.fname
FROM holidays h
JOIN users u
ON u.id = h.userid
WHERE h.status = 0
by the alias (FROM users u) you can select column from users table by u.fname
First try to right join to the User table. If you just want the fname then select the column name in the SELECT query, as SELECT * takes more time then SELECT column name.

How can I filter out results based on another table. (A reverse join I guess?)

Basically, I have a table which contains two fields: [id, other] which have user tokens stored in them. The goal of my query is to select a random user that has not been selected before. Once the user is selected it is stored in the table shown above. So if Jack selects Jim randomly, Jack cannot select Jim again, and on the flip side, Jim cannot select Jack.
Something like this is what comes to mind:
SELECT * FROM users
WHERE (SELECT * FROM selected WHERE (id=? AND other=?) OR (id=? AND other=?));
Well, first of all I've read that uses sub-queries like this is extremely inneficient, and I'm not even sure if I used the correct syntax, the problem is however, that I have numerous tables in my scenario which I need to filter by, so it would look more like this.
SELECT * FROM users u
WHERE (SELECT * FROM selected WHERE (id=? AND other=?) OR (id=? AND other=?))
AND (SELECT * FROM other_table WHERE (id=? AND other=?) OR (id=? AND other=?))
AND (SELECT * FROM diff_table WHERE (id=? AND value=?))
AND u.type = 'BASIC'
LIMIT = 1
I feel like there's a much, much more efficient way of handling this.
Please note: I don't want a row returned at all if the users id is present in any of the nested queries. Returning "null" is not sufficient. The reason I have the OR clause is because the user's id can be stored in either the id or the other field, so we need to check both.
I am using Postgre 9.5.3, but I added the MySQL tag as the code is mostly backwards comptable, Fancy Postgre only solutions are accepted(if any)
You can left join to another table, which produces nulls where no record is found:
Select u.* from users u
left selected s on s.id = u.id or s.other = u.other
where s.id is null
The or in a join is different, but should work. Example is kinda silly...but as long as you understand the logic. Left join first table to second table, where second table column is not null means there was atleast one record found that matched the join conditions. Where second table column is null means no record was found.
And you are right...avoid the where field = (select statement) logic when you can, poor performer there.
Use an outer join filtered on missed joins:
SELECT * FROM users u
LEFT JOIN selected s on u.id in (s.id, s.other) and ? in (s.id, s.other)
WHERE u.id != ?
AND s.id IN NULL
LIMIT 1

How to select two tables and combined them together if null isn't present

Currently I can search two tables (events table and the users table) and combined them together using the following:
SELECT e.*, u.user_first_name, u.user_last_name
FROM users u, events e
WHERE e.event_user_id = u.user_id
ORDER BY e.event_id DESC
This will allow me to search everything from the events table and the first and last name from the users table.
But the problem occurs when the event_user_id can be NULL, meaning if there is a user set, I want to include their first and last name, but if there isn't then I just want that field to be blank.
SELECT e.*, u.user_first_name, u.user_last_name
FROM users u, events e
WHERE e.event_user_id = u.user_id
OR e.event_user_id IS NULL
ORDER BY e.event_id DESC
I know the above example isn't correct. My question is, how can I select two tables where the main table has an optional event_user_id, if it is not NULL, then combine with the users table to get the first and last name?
Is it just more reliable to have two separate queries?
As Ivan mentioned in the comments to my question, the correct way to successfully carry out the query I want is to use a left join, so I did a bit of research and I found the right query for me:
SELECT events.*, users.user_first_name, users.user_last_name
FROM events
LEFT OUTER JOIN users
ON events.event_user_id = users.user_id;
If event_user_id is present, then the user_first_name and user_last_name will be added to the row, however, if event_user_id is NULL then both the first and last name will also be NULL. Exactly what I wanted.

In joins if specific column is null than in return resulting query does not retun a whole row

I am trying to get records from multiple tables. If "im.path" column is null in the db against the specific id, then in result whole row is skipped.
I want that if image does not exit against the specific id, then in result it shows the row with a image path column empty.
My query is below.
select distinct p.person_id as p_id,i.current_status,p.*, im.path from invitation i
join person p on i.person_id=p.person_id
join user u on p.person_id=u.person_id
join image im on u.user_id=im.entity_id
where sender_account_id=40 or i.person_id=40 and invitation_category_id=1
In this case if im.path column is empty, then whole record is skipped, that is what I do not want
Thanks in Advance.
SELECT distinct p.person_id as p_id, i.current_status, p.*, im.path
FROM invitation i
INNER JOIN person p on i.person_id=p.person_id
INNER JOIN user u
on p.person_id=u.person_id
LEFT join image im
on u.user_id=im.entity_id
WHERE (sender_account_id=40
or i.person_id=40)
and invitation_category_id=1
I'm also suspicious of not having ()'s around the OR statement here; so I added them.
also without knowing where sender and invitation_category_ID reside, they may limit the results inappropriatly from the left join. So what table are sender_account and invitation_category_ID in?
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/ is a great link explaining join types.