I have 2 tables:
Customers:
- ID
- NAME
Modulemembers:
- ID
- customer_id
- enabled
I use this to enable a function of my site for some customers.
I have a form where the admin of the site can add the module for a customer, so i need a query that looks for customers that are NOT member of the modulemembers table.
I made this:
SELECT customers.id,
customers.name
FROM customers,
modulemembers
WHERE customers_id != modulemembers.cust_id
ORDER BY customers.name
but it does not work. What am I doing wrong?
You can use NOT EXISTS in the WHERE clause to get the result:
SELECT c.id,
c.name
FROM customers c
WHERE not exists (select customer_id
from modulemembers m
where c.id = m.customer_id)
order by c.name
You can use a LEFT OUTER JOIN and filter based on NULLs. The query below will pull in all results from the customers table and the modulemembers table. If there is not a match in the modulemembers table then the custid will be NULL.
SELECT c.id, c.name
FROM customers c
LEFT OUTER JOIN modulemembers m ON c.customers_id = m.cust_id
WHERE m.custid IS NULL
ORDER BY c.name
Try something like this:
SELECT c.ID AS customerId,
c.NAME AS fullName,
m.ID AS memberId
FROM Customers AS c
LEFT JOIN Modulemembers AS m ON m.customer_id = c.ID
WHERE m.ID IS NULL;
Related
There are two tables:
Customers:
ID
Name
Surname
City
Orders:
OrderId
CustomerId
Purchase
Price
I'm trying to find customer id,name,surname where he hasn't Purchase "Pizza".
Any help to fix my query? I tried with cp.Purchase != "Pizza" but doesn't work
SELECT DISTINCT ID,FirstName,LastName
FROM Customers c
INNER JOIN Orders cp ON c.ID = cp.OrderID
ORDER BY c.ID
WHERE cp.Purchase LIKE '%Pizza%'
try this
select * from Customers where Id not in (
select CustomerId From Orders WHERE cp.Purchase LIKE '%Pizza%'
)
The right query is
SELECT DISTINCT c.ID, c.Name, c.Surname
FROM Customers c JOIN Orders o on c.ID = o.CustomerID
WHERE c.ID <> ALL (
SELECT c2.ID
FROM Customers c2 JOIN Orders o2 on c.ID = o2.CustomerID
WHERE o2.Purchase = 'Pizza')
This is because you are looking for who never bought a pizza, so you will select data of customers which ID never appear (<> ALL) in orders table in a record where a pizza was bought.
By the way, check also SQL base, try understand before getting the answer.
I have these tables : customers, customer_invoices, customer_invoice_details, each customer has many invoices, and each invoice has many details.
The customer with the ID 574413 has these invoices :
select customer_invoices.customer_id,
customer_invoices.id,
customer_invoices.total_price
from customer_invoices
where customer_invoices.customer_id = 574413;
result :
customer_id invoice_id total_price
574413 662146 700.00
574413 662147 250.00
each invoice here has two details (or invoice lines) :
first invoice 662146:
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662146;
result :
detail_id invoice_id detail_total_price
722291 662146 500.00
722292 662146 200.00
second invoice 662147 :
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662147;
result :
detail_id invoice_id detail_total_price
722293 662147 100.00
722294 662147 150.00
I have a problem with this query :
select customers.id as customerID,
customers.last_name,
customers.first_name,
SUM(customer_invoices.total_price) as invoice_total,
SUM(customer_invoice_details.total_price) as details_total
from customers
join customer_invoices
on customer_invoices.customer_id = customers.id
join customer_invoice_details
on customer_invoice_details.customer_invoice_id = customer_invoices.id
where customer_id = 574413;
unexpected result :
customerID last_name first_name invoice_total details_total
574413 terry amine 1900.00 950.00
I need to have the SUM of the total_price of the invoices, and the SUM of the total_price of the details for each customer. In this case I'm supposed to get 950 as total_price for both columns (invoice_total& details_total) but it's not the case. what am I doing wrong & how can I get the correct result please. The answers in similar topics don't have the solution for this case.
When you mix normal columns with aggregate functions (for example SUM), you need to use GROUP BY where you list the normal columns from the SELECT.
The reason for the excessive amount in total_price for invoices is that the SUM is also calculated over each detail row as it is part of the join. Use this:
select c.id as customerID,
c.last_name,
c.first_name,
SUM(ci.total_price) as invoice_total,
SUM((select SUM(d.total_price)
from customer_invoice_details d
where d.customer_invoice_id = ci.id)) as 'detail_total_price'
from customers c
join customer_invoices ci on ci.customer_id = c.id
where c.id = 574413
group by c.id, c.last_name, c.first_name
db-fiddle
I used join against sub queries and then did a sum on the sums
SELECT c.id as customerID,
c.last_name,
c.first_name
SUM(i.sum) as invoice_total,
SUM(d.sum) AS details_total
FROM customers c
JOIN (SELECT id, customer_id, SUM(total_price) AS sum
FROM customer_invoices
GROUP BY id, customer_id) AS i ON i.customer_id = c.id
JOIN (SELECT customer_invoice_id as id, SUM(total_price) AS sum
FROM customer_invoice_details
GROUP BY customer_invoice_id) AS d ON d.id = i.id
WHERE c.id = 574413
GROUP BY c.id, c.name
The issue is in the joining logic. The table customers is used as the driving table in the joins. But in the second join, you are using a derivative key column from the first join, to join with the third tables. This is resulting in a Cartesian output doubling the records from the result from the nth-1 join, which is leading to customer_invoices.total_price getting repeated twice, hence the rolled up value of this field is doubled.
At a high level I feel that the purpose of rolling up the prices is already achieved in SUM(customer_invoice_details.total_price).
But if you have a specific project requirement that SUM(customer_invoices.total_price) should also be obtained and must match with SUM(customer_invoice_details.total_price), then you can do this:
In a separate query, Join customer_invoice_details and customer_invoices. Roll up the pricing fields, and have a result such that you have only one record for one customer ID.
Then use this as a sub-query and join it with the customers table.
You are aggregating along multiple dimensions. This is challenging. I would suggest doing the aggregation along each dimension independently:
select c.id as customerID, c.last_name, c.first_name,
ci.invoice_total,
cid.details_total
from customers c join
(select ci.sum(ci.total_price) as invoice_total
from customer_invoices ci
group by ci.customer_id
) ci
on ci.customer_id = c.id join
(select ci.sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
group by ci.customer_id
) cid
on cid.customer_id = c.id
where c.id = 574413;
A faster version (for one customer) uses correlated subqueries:
select c.id as customerID, c.last_name, c.first_name,
(select ci.customer_id, sum(ci.total_price) as invoice_total
from customer_invoices ci
where ci.customer_id = c.id
) as invoice_total,
(select ci.customer_id, sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
where ci.customer_id = c.id
) as details_total
from customers c
where c.id = 574413;
I have two tables, customers and Orders
Customers columns are
CustomerID,
Username,
Password,
Firstname,
Surname,
Email,
Mobile
Orders columns are
OrderID,
CustomerID,
Date,
Time,
Price,
Complete
I want to select all of the firstname and surnames from all the orders that have been complete. And yes It could be so that [0] = John Smith and [1] also = John Smith.
What I was thinking was
SELECT FirstName, Surname from order, customers
WHERE Complete = 'Yes' AND order.CustomerID = customer.CustomerID;
So first it looks at if the order is complete. If it is then it will look at the customer ID, then it will go to customers and get the firstname and surname of that customer then store it in the datatable.
Thank you for any help!!!
You could use EXISTS, the following query will return all customers that don't have incomplete (=0) orders:
select c.firstname, c.lastname
from customers c
where
not exists (select * from orders o
where c.customerid = o.orderid
and o.complete = 'No')
but it will also return customers that have no orders. If you want to exclude customers with no orders you could use an additional exist clause:
select c.firstname, c.lastname
from customers c
where
not exists (select * from orders o
where c.customerid = o.orderid
and o.complete = 'No')
and exists (select * from orders o where c.customerid = o.orderid)
or a group by clause:
select c.firstname, c.lastname
from customers c inner join orders o on c.customerid = o.customerid
group by c.customerid, c.firstname, c.lastname
having sum(o.complete='No') = 0
This will give you list of Firstname, Surname even though they don't have orders.
SELECT Customers.Firstname, Customer.Surname
FROM Customers, Orders
WHERE Orders.Complete = 'Yes'
LEFT JOIN Customers.CustomerID = Orders.CustomerID
I'd go with this personally:
SELECT c.Firstname, c.Surname FROM Customers c
INNER JOIN Orders o
ON c.CustomerID=o.CustomerID
WHERE o.Complete='Yes'
I like to be as explicit as possible with my queries, so anyone else who has to read my code understands the what, why and how. Though shouldn't you also select something to identify the order? Otherwise all you have is a list of names.
--Unique list of customer id, customer first name and customer surname.
SELECT DISTINCT
customers.customerid
, customers.firstname
, customers.surname
FROM orders
INNER JOIN customers
ON
customers.customerid = orders.customerid
AND orders.complete = 'Yes'
--Unique list of customer first name and customer surname, regardless
--if same names are tied to different customerid.
SELECT DISTINCT
customers.customerid
, customers.firstname
, customers.surname
FROM orders
INNER JOIN customers
ON
customers.customerid = orders.customerid
AND orders.complete = 'Yes'
Remove DISTINCT word if you want duplicates.
I have one table of client details identified by an ID that looks like this:
ID (the clientcode), Name, Details
I would like to reference the ID from another table with sales information and pick up the name of the client in the query.
My original query string that picked up just the ID (clientcode) is this:
SELECT clientcode, SUM(sales) FROM inventory WHERE manufacturer='1'
GROUP BY client code ORDER BY SUM(sales) DESC
I would like to also pick up the Name of the client referenced by clientcode.
I tried a few LEFT JOINs but couldn't get the queries working.
SELECT i.clientcode
, c.name
, SUM(i.sales)
FROM inventory i
LEFT
JOIN clientdetails c
ON c.id = i.clientcode
WHERE i.manufacturer='1'
GROUP BY i.clientcode, c.name
ORDER BY SUM(i.sales) DESC
This should do it
SELECT c.ID, c.name, SUM(i.sales)
FROM inventory i
JOIN clients c ON c.ID = i.clientcode
WHERE i.manufacturer='1'
GROUP BY c.ID, ORDER BY SUM(i.sales) DESC
A simple query to achieve this is:
SELECT i.clientcode, d.name, SUM(i.sales) FROM inventory i, details d
WHERE i.manufacturer='1'
AND d.clientcode = i.clientcode
GROUP BY i.clientcode ORDER BY SUM(i.sales) DESC
Here, try thisone out.
SELECT inventory.clientcode,
SUM(inventory.sales),
clientdetails.Name
FROM inventory
INNER JOIN clientdetails
ON inventory.clientcode = clientdetails.clientcode
WHERE inventory.manufacturer='1'
GROUP BY inventory.clientcode, clientdetails.Name
ORDER BY SUM(inventory.sales) DESC
SELECT a.clientcode,
SUM(a.sales),
b.Name
FROM inventory a
INNER JOIN clientdetails b
ON a.clientcode = b.clientcode
WHERE a.manufacturer='1'
GROUP BY a.clientcode, b.Name
ORDER BY SUM(a.sales) DESC
I have the folowing tables.
ORDER
OrderNumber
CustomerNumber
EmployeeNumber
OrderDate
CUSTOMER
CustomerNumber
Name
Address
EMPLOYEE
EmployeeNumber
Name
Address
ORDERDETAIL
OrderNumber
Qty
Description
Price
Let say ORDERDETAIL table has 10 records
I would like to write a query that will return 10 records from ORDERDETAIL table to include Employee name, employee address, customer name, customer address and and order Date.
I know that I could write a query and use INNER JOIN to get the info from ORDER table, but how do you create the rest of query to get the info from the CUSTOMER and EMPLOYEE tables.
SELECT *
FROM OrderDetail D
INNER JOIN Order O
ON D.OrderNumber = O.OrderNumber;
Just add some more joins...
SELECT *
FROM OrderDetail D
JOIN Order USING (OrderNumber)
JOIN Customer USING (CustomerNumber)
JOIN Employee USING (EmployeeNumber)
You might want to re-order the JOINs in order to have the smallest tables first, as this could provide you with some performance boost (depending on your server's version, the most recent will optimize the join for you and might actually execute the joins in the "probably best" way).
Also, in the MySQL dialect at least, JOIN implicitly expands to INNER JOIN, and writing
A JOIN B USING (COL)
is equivalent to writing
A JOIN B ON (A.COL = B.COL)
SELECT *
FROM OrderDetail D
INNER JOIN Order O ON D.OrderNumber = O.OrderNumber
INNER JOIN Eployee E on O.EployeeNumber = E.EployeeNumber
INNER JOIN Customer C on O.CustomerNumber = C.CustomerNumber
if you have foreign key reference between
ORDER.EmployeeNumber and EMPLOYEE.EmployeeNumber
ORDER.CustomerNumber and CUSTOMER.CustomerNumber
then try this
SELECT
E.name AS employeeName,
E.Address AS employeeAddress,
C.name AS customerName,
C.Address AS customerAddress.
O.OrderDate
FROM OrderDetail D
INNER JOIN Order O ON D.OrderNumber = O.OrderNumber
INNER JOIN EMPLOYEE E ON E.EmployeeNumber = 0.EmployeeNumber
INNER JOIN CUSTOMER C ON C.CustomerNumber= 0.CustomerNumber
LIMIT 0,10