Select rows that meet condition of other row - mysql

I want to ask how can I check all rows in one column (which is foreign key) and then
if all that rows meet some condition then to get the result from it in MySQL.
For example I have three tables as follow
Products
ID Price
1 70
2 20
3 55
Bill
ID (others columns are not important)
100
200
300
ProductsBill
ID BillID ProductID
1 100 1
2 100 3
3 200 2
4 200 1
5 300 2
Now I want so select all BillsID where ALL products in that Bill has a price higher than 50,
which in this case should return the Bill with ID 100 because only this bill contains products which price are higher than 50
Thank you in advance.

Join the tables, group by billid and set the condition in the having clause:
select
pb.billid
from productsbill pb inner join products p
on p.id = pb.productid
group by pb.billid
having min(p.price) > 50

Try:
SELECT DISTINCT BillID FROM ProductsBill WHERE BillID NOT IN (
SELECT DISTINCT pb.BillID FROM
ProductsBill pb JOIN Products p on pb.ProductID = p.ID
WHERE p.PRICE < 50
);
The subquery ...
SELECT DISTINCT pb.BillID FROM
ProductsBill pb JOIN Products p on pb.ProductID = p.ID
WHERE p.PRICE < 50
... selects all BillID's where there is at least one product with an associated price < 50. The outer query then selects all BillId's that are in the ProductBill table that do not have at least one product with an associated price < 50.

Related

name and sum from 2 different tables

I have 2 tables.
table customer have. id , name , age
table order have . id, customer_id , order_amount , order date.
I want to show all name from customer table and sum of order amount from order table according to customer.
customer_id
Name
age
1
Alice
24
2
Bob
52
3
Carol
45
4
Dave
51
order_id
customer_id
order_amount
order_date
1
2
50
2012-4-5
2
1
27
2012-8-1
3
2
12
2013-5-20
4
4
25
2014-1-25
5
4
30
2014-5-30
6
1
20
2014-6-22
EDIT
I tried this but it gives me only bob and sum of all columns instead of separate sum of customers
SELECT customers.name, SUM(orders.order_amount) FROM `orders` INNER JOIN customers WHERE orders.customer_id = customers.customer_id;
Joining condition must be on ON clause, not in WHERE.
You must specify for what group the sum must be calculated.
SELECT customers.name, SUM(orders.order_amount)
FROM `orders`
INNER JOIN customers ON orders.customer_id = customers.customer_id
GROUP BY customers.name;

Mysql SUM and GROUP BY from 3 tables

I have 3 database tables as follows:
projects:
id
project_name
project_location
status
project_expenses
id
project_id
expense_category
expense_subcategory
amount
userid
date
payment_status
project_status
project_income
id
project_id
project_income
date
userid
project_status
projects.id, project_expenses.project_id and project_income.project_id are related.
I need to create a query displaying Project_ID,Project_Name,SUM of Project_Income,SUM of Project_expenses
I tried the following query but not getting correct result.
SELECT p.id AS id, p.project_name AS project_name, SUM(i.project_income) AS income, SUM(e.amount) AS expenses
FROM project_income i, project_expenses e, projects p
WHERE i.project_id = p.id AND e.project_id = p.id AND p.status = 'Active'
GROUP BY id
I have currently 2 rows in project_income and 4 rows in project_expenses. The result is project_income displays double the values. Something is wrong with my JOIN.
Being a newbie I am unable to understand what i am doing wrong?? Requesting help...
Use sub-selects in the query result columns. No need for GROUP BY.
SELECT p.id
, p.project_name
, ( SELECT SUM(i.project_income)
FROM project_income i
WHERE i.project_id = p.id
) AS income
, ( SELECT SUM(e.amount)
FROM project_expenses e
WHERE e.project_id = p.id
) AS expenses
FROM projects p
WHERE p.status = 'Active'
The problem with the query in the question is best explained with an example.
You say there are 2 rows in project_income and 4 rows in project_expenses. Let say the 2 incomes are 1000 and 1500, and the 4 expenses are 615, 750, 840, and 900.
Since there are no restrictions between them, that means you'll get the cross join, i.e. 8 records:
income expense
1000 615
1000 750
1000 840
1000 900
1500 615
1500 750
1500 840
1500 900
Now, when you sum income you get 4 times the value you want, and when you sum expense you get 2 times the value you want.

Use COALESCE within SUM in MySQL SELECT statement

I have the following tables:
Table users
id name base_discount
1 jack 10
2 michael 20
3 richard 30
Table item
id name category_id price
1 hammer 1 10
2 knife 2 15
3 spoon 2 12
4 plate 3 20
5 tree 4 400
Table category
id name
1 tools
2 kitchen
3 dishes
4 garden
Table discount_category
id user_id category_id discount
1 1 1 20
2 1 3 25
3 3 3 10
4 1 2 15
Table discount_item
id user_id item_id discount
1 2 1 50
2 1 2 50
Now what I want to achieve. I want to attach the discount per item that a user has to the correct item. If that is not available (NULL) I want to attach the discount per category that a user has. And if that is not available (NULL), I want to attach the base discount that a user has. With the discount I then calculate the new price of the item. However, when I try using COALESCE() within SUM() I get a syntax error. What am I doing wrong?
Below is my current query:
SELECT item.id, item.name, category.id,
category.name AS category_name, item.price, SUM((100 -
COALESCE(
(
SELECT discount_item.discount
FROM discount_item
INNER JOIN users ON discount_item.user_id = users.id
WHERE users.id = '1' AND discount_item.item_id = item.id
),
(
SELECT discount_category.discount
FROM discount_category
INNER JOIN users ON discount_category.user_id = users.id
WHERE users.id = '1' AND discount_category.category_id = item.category_id
),
(
SELECT users.base_discount
FROM users
WHERE users.id = '1'
)
)) / 100 * item.price) AS new_price,
FROM item
INNER JOIN category ON item.category_id = category.id;
Please also see the below link for an SQL Fiddle (couldn't do it on sqlfiddle.com as it wouldn't load). In the example I have appended a suffix to each table name.
http://rextester.com/LCCKSD59098
You have an extra comma after new_price and before FROM ITEM, hence the error.
Rextester Demo
Do not select other columns in select if you are not using them in group by, as in other relational RDBMS, you will get error.
Also use alias for table names for better readibily and to avoid confusion.

SQL limit SELECT but not JOIN

I'm implementing pagination on my BD. My problem is when I want limit the SELECT statement but not the JOIN. Example, a product can got many prices:
SELECT * FROM product
LEFT JOIN price ON product.id == price.id_product
LIMIT 20
But I want to get 20 products with each one with their prices. How I can limit the statement SELECT, but not LEFT JOIN.
Example:
product price.id price.id_pruct price.price
1 1 1 50
2 2 1 30
3 3 1 40
4 1 20
5 2 30
SELECT * FROM product
LEFT JOIN price ON product.id == price.id_product
LIMIT 3
Return:
product price.id id_prodcut price
1 1 1 50
1 2 1 30
1 3 1 40
But I Want
product price.id id_prodcut price
1 1 1 50
1 2 1 30
1 3 1 40
1 4 1 20
2 5 2 30
3 . . .
Three products (limit 3)
Thanks. I hope you can help me.
Modify your query to limit the number of product rows before joining it to the price table. This means we want to to join the results of a query to a table, or in other words, we write a query containing a subquery:
SELECT *
FROM (
SELECT *
FROM product
ORDER BY id_product
LIMIT 3
) p
LEFT JOIN price ON p.id = price.id_product
Hope that helps.
I would write a subquery to get the three first products (or whatever condition you choose) like this:
SELECT id
FROM product
ORDER BY id
LIMIT 3;
Once I have that, I can select everything from the price table as long as the id is in that subquery. You can do this using a join:
SELECT p.*
FROM price p
JOIN(
SELECT id
FROM product
ORDER BY id
LIMIT 3) tmp ON tmp.id = p.product_id;
Here is an SQL Fiddle example using your sample data, and I also added a row that won't be returned so you can see that it works.

MySQL join, count and group by multiple database

I have this working query
SELECT t1.id as stockid, t1.description as stockdescription, t2.inkoop as price , COUNT(t2.inkoop) as cnt,
(t2.inkoop * COUNT(t2.inkoop)) as totalamount
FROM database1.table_products t1
LEFT JOIN database1.table_stock t2 ON t1.id = t2.stock_id
WHERE 1
GROUP BY t2.inkoop
ORDER BY t1.id ASC
1 database, 2 tables:
t1 is the products 'description' database with ids and description
t2 is the stock, which has a lot of products for what price (purchased) and referenced by stock_id
Output:
id stockdescription price cnt totalamount
1 Product1 1067 15 16005
1 Product1 1290 103 132870
2 Product2 2750 70 192500
3 Product3 500 0 0
But now i have this 2nd database (database2) with a second inventory table (stock2) (exactly the same structure as database1.table_stock)
How do i alter my query so i can also add 'cnt2' and change total to my results?
Like this:
id stockdescription price cnt cnt2 totalcnt totalamount
1 Product1 1067 15 0 15 16005
1 Product1 1290 103 0 103 132870
2 Product2 2750 70 5 75 206250
3 Product3 500 0 4 4 2000
You can join multiple tables, but you'd get the full join of the two stock tables, which means you'd get wrong counts after the GROUP BY. You can avoid that by nesting your queries, e.g. along these lines:
SELECT sub.*, COUNT(stock2.inkoop) AS cnt2
FROM ( <paste your query here> ) AS sub
LEFT JOIN database2.stock2 AS stock2 ON sub.stockid = stock2.stock_id
GROUP BY sub.stockid
ORDER BY sub.stockid ASC
Now you have two left joins, each with its own GROUP BY. So each left join only sees a single left hand table factor, and you won't get duplicates caused by joining too many tables at once.