I have two tables (MAILS & customers) in my MySQL db both having a column email storing email addresses.
Now I'd like to select every row from these two tables where emails.email!=customers.email.
When I do a simple SELECT * FROM emails, customers WHERE emails.email != customers.email, I get each emails.email listed with a data from the customers table.
How do I do that? Can I use DISTINCT but apply it only to the data coming from the customers table?
If you're wanting a unique list of email addresses found in either the emails table or the customers table where there is not a match between them on the email field this will do the trick:
SELECT DISTINCT COALESCE(e.Email, c.Email) as Email
FROM Emails e FULL OUTER JOIN Customers c ON e.Email = c.Email
WHERE e.Email IS NULL OR c.Email IS NULL
Coincidentally, this type of circumstance is one of the very few situations in which I have ever found the FULL OUTER JOIN to be of particular use...
A 'not-equals' join is very seldom helpful unless there is in fact another column that can be joined for equality. So, if you have a PersonID column in each of the two tables, then you can do:
SELECT m.*, c.*
FROM mails AS m
JOIN customers AS c ON c.PersonID = m.PersonID
WHERE c.email != m.email
But without that extra condition, you have what is close to a Cartesian Product of the two tables, where almost every row in one table is matched with almost every row in the other (because of the not equals condition). Without the not equals condition, the result set would be only slightly larger.
Related
i have two tables in mysql. The first one holds companies and the second one holds contacts that work for these companies.
There are companies without contacts, and there are several contacts that can work for one company, but there are never contacts without a company.
The tables look like this:
company table
company_id
company_name
company_telephone
contacts table
contact_id
works_for_company_id
contact_fullname
contact_telephone
I am trying to combine both tables with one select statement in order to create a list of telephone numbers for each and every entry, e. g. one company with two contacts results in three entries, each with the company name and telephone number in one row.
I tried JOIN statements, which all resulted in displaying the contacts but not the companies behind it, i tried UNION (didn't work because of different column names). What else am I missing? Any help would be appreciated.
You combine both join and union - but you will have to rename the differently named columns (via AS):
SELECT company_id, company_telephone AS phone FROM company
UNION
SELECT company_id, contact_telephone AS phone FROM company JOIN contacts ON ...
All you need is direct straight join to get all the details. You can replace * with relevant column names:
SELECT *
FROM CONTACTS_TABLE con
JOIN COMPANY_TABLE cta ON cta.company_id = con.works_for_company_id
As people told you in previous comments, you need a join/inner join
SELECT comp.company_id, cont.contact_fullname
FROM company comp
INNER JOIN contacts cont ON comp.company_id = cont.works_for_company_id;
There are companies without contacts SO you need to use LEFT JOIN
SELECT com.company_name,com.telephone ,com.company_id, con.contact_fullname
FROM company com
LEFT JOIN contacts con ON com.company_id = con.works_for_company_id;
The UNION operator is used to combine the result-set of two or more SELECT statements.
Each SELECT statement within UNION must have the same number of
columns
The columns must also have similar data types
The columns in each SELECT statement must also be in the same order
SELECT company.company_name, company.company_telephone
FROM company
WHERE company.company_id =1
UNION
SELECT contact.contact_fullname, contact.contact_fullname
FROM company
JOIN contact ON company.company_id = contact.works_for_company_id
WHERE company.company_id =1
LIMIT 0 , 30
I currently have 4 SQL tables that look like this:
CustomersTable, RegistrationTable, OrdersTable and OffersTable
enter image description here
I need to write a SELECT statement that retrieves all customers from the CustomersTable (all the fields) that contain rows that match the RegistrationTable Or rows that match the OrdersTable with status "closed", in the result table shouldn't display duplicate customers.
As you realized, CustomersTable and RegistrationTable have the field in common "customerId", but between CustomersTable and OrdersTable there is no field in common. However there is another table (OffersTable) which has the fields "customerId" and "ID", to query information to Customers and Orders table respectively. Remember that a customer who appears in OfferTable not necessarily will appear in OrderTable or just the status is NOT "Closed"
So based on my example tables above, if I were to run the query, it would return the following result:
enter image description here
In the result table shouldn't display duplicate customers.
I really appreciate your help.
Thanks for your time !!
Note - I am using MySQL
Try Using "Union" and "inner join" with every table Like below:
Select Customers.* from Customers inner join Registration on Customers. customerId= Registration.customerId
union
Select Customers.* from Customers inner join offers on Customers.customerId=offers.customerId
inner join Orders on orders.Id= offers.Id and Orders.Status='closed'
I would think exists or in, given what you want. Your description of the table is a bit cumbersome -- which is why sample data in the question is so helpful.
The resulting query would look something like this:
select c.*
from customers c
where exists (select 1 from registrations r where r.customerid = c.customerid) or
exists (select 1
from offers o join
orders oo
on o.id = oo.orderid
where o.customerid = c.customerid and
oo.status = 'closed'
);
The column names may not be quite right.
I have two tables clients and transactions and I need to take a query from these two tables in a way which all the clients should select with the total of their transactions.
My problem is when I do a query from these two tables and set the condition; which transactions should have the clients id it shows only those clients that have record in transaction table, but I want it display all the clients even if they don't have any transaction(it can display zero instead sum of transaction).
I know because of condition which belongs to transaction table, query doesn't select persons in clients table which doesn't meet the query requirement, but how can I select all the clients and sum of their transactions or put zero if they don't has any transaction.
this is a short view of tables (only those columns I used in query)
ID Name Company Phone //clients table
ID Client_id Incoming ... //transaction table
Thank you in advance and sorry for my bad english
In addition, you can also do this with a correlated subquery:
SELECT c.*,
(select sum(t.incoming) - sum(t.outgoing)
from transactions t
where t.client_id = c.id
) as total
from clients c;
Under some circumstances, this could have better performance.
SELECT c.Name, count(t.ID)
FROM clients c
left join transactions t on c.CustomerID = t.Client_id
group by t.client_id
you could use a left join, something like :
SELECT *
FROM clients
LEFT JOIN transaction ON client.id = transaction.Client_id
You would get all clients, empty rows from transaction would be set to null, so you'll have to change that to 0
Below is my sql statement
SELECT a.purchase_id,
b.username,
a.purchase_packageid,
a.purchase_tradelimit,
a.purchase_pincode,
a.purchase_datetime,
c.packages_name ,
FROM purchase a,
accounts b,
packages c
WHERE a.purchase_userid=b.UserId
AND c.packages_id=a.purchase_packageid
Basically the issue is I got 3 tables
Accounts
Purchase
Packages
The main table is Purchase, inside the table there is purchase_userid , which I need to use it to get username from table accounts
So the problem now is I got rows where the purchase_userid is blank, because its blank, it won't draw its record as null.
The only record that show in this sql statement is only those with purchase_userid,
As the value for purchase_userid will be fill up later for my web app,
I still want to select rows without purchase_userid and those with purchase_userid
Thanks for helping !!
You need to use a left join to load all records in Purchase even when no matching records are found in Accounts.
SELECT a.purchase_id, b.username, a.purchase_packageid, a.purchase_tradelimit, a.purchase_pincode, a.purchase_datetime, c.packages_name
FROM purchase a LEFT JOIN accounts b
ON a.purchase_userid=b.UserId
JOIN packages c
ON c.packages_id=a.purchase_packageid
This post explains the different kinds of joins pretty well: What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?
You're using the old-timey syntax for INNER JOINs between your tables, when what you need is LEFT JOIN operations. Try this:
SELECT a.purchase_id,
b.username,
a.purchase_packageid,
a.purchase_tradelimit,
a.purchase_pincode,
a.purchase_datetime,
c.packages_name
FROM purchase AS a
LEFT JOIN accounts AS b ON a.purchase_userid = b.UserId
LEFT JOIN packages AS c ON a.purchase_packageid = c.packages_id
This works better for you because the kind of JOIN you were using suppresses records from your a table when they weren't matched in your b or c table. This LEFT JOIN will leave the a table records in place, and put NULL values where you are calling for data from the other two.
I have a printed table here, and I issue a query to attempt to join the tables where the Tech_id, clients_id, job_id, part_id should populate with corresponding key in their tables / column too.
Here is my query:
SELECT * FROM work_orders, technicians as tech, parts_list as parts, job_types as job, clients as client
LEFT JOIN technicians ON tech_id = technicians.tech_name
LEFT JOIN parts_list ON part_id = parts_list.Part_Name
LEFT JOIN job_types ON job_id = job_types.Job_Name
LEFT JOIN clients ON clients_id = clients.client_name
I've messed around with multiple different variations, this one seem to be syntax correct, but now I'm getting: Column 'clients_id' in on clause is ambiguous
I'm sure that it will happen for not only clients but maybe others. I want to be able to print the table as in the picture above, but with the clients listed. Is it possible to be done via one query as well? thanks.
You have two problems.
First (this might not be your problem, but that's a "good practice"), you shouldn't use SELECT *, as you could indeed have a field with same name in different tables.
This is one (of the many) good reason to avoid * in a Select clause.
Then, your main problem is that you select tables in your from clause, and then again by joining.
Problematic line :
FROM work_orders, technicians as tech, parts_list as parts, job_types as job, clients as client
So (I don't know your table structure, so they may be errors, but you've got the idea)
SELECT
w.client_id,
t.tech_name
--etc
FROM work_orders w
LEFT JOIN technicians t ON c.tech_id = t.tech_name
LEFT JOIN parts_list p ON c.part_id = p.Part_Name
LEFT JOIN job_types j ON w.job_id = j.Job_Name
LEFT JOIN clients c ON w.clients_id = c.client_name
This means that clients_id exists in multiple tables. You need to specify which one you want. So if you for example want the clients_id of the clients table, do SELECT clients.clients_id
If all the fiels listed in your question are in the clients table you could do:
SELECT clients.* FROM work_orders, technicians as tech, parts_list as parts, job_types as job, clients as client
LEFT JOIN technicians ON tech_id = technicians.tech_name
LEFT JOIN parts_list ON part_id = parts_list.Part_Name
LEFT JOIN job_types ON job_id = job_types.Job_Name
LEFT JOIN clients ON clients_id = clients.client_name