I have three tables like below.
Courses:
Id Name
1 A
2 B
3 C
4 D
Prices:
Id CId Price
1 1 200
2 2 150
3 3 500
4 4 300
Payment:
Id CId
1 1
2 4
If a record of payment for Course record exists, then Price should be -1. I want to get result like below:
Id Name Price
1 A -1
2 B 150
3 C 500
4 D -1
How should I query mysql?
Try This
SELECT c.Id, c.name,
CASE WHEN pa.id IS NOT NULL THEN -1 ELSE pr.price
END as Price
FROM Courses c
LEFT JOIN Prices pr
ON c.Id = pr.CId
LEFT JOIN Payment pa
ON c.id = pa.CId;
OR
SELECT c.Id, c.name,
CASE WHEN pa.id IS NULL THEN pr.price ELSE -1
END as Price
FROM Courses c
LEFT JOIN Prices pr
ON c.Id = pr.CId
LEFT JOIN Payment pa
ON c.id = pa.CId;
Working code:
select c.id, c.Name, IF(pm.CId is null, p.Price, -1) as Price
from Prices p left join Payment pm
on p.CId = pm.CId
inner join Courses c
on p.CId = c.id
order by c.id
SqlFiddle: http://sqlfiddle.com/#!9/f1b715/3
SQL Fiddle Demo Thanks to #Barmar
SELECT C.ID, C.NAME, CASE WHEN pay.CId IS NULL THEN P.PRICE
ELSE -1
END as Price
FROM Courses C
JOIN Prices P
ON C.Id = P.CId
LEFT JOIN Payment pay
ON C.id = pay.CId
ORDER BY P.id
OUTPUT
| Id | Name | Price |
|----|------|-------|
| 1 | A | -1 |
| 2 | B | 150 |
| 3 | C | 500 |
| 4 | D | -1 |
SELECT p.id,c.NAME, CASE WHEN p.cid=e.cid THEN -1 ELSE p.price END AS price
FROM prices p
LEFT JOIN courses c
ON c.id=p.ID
LEFT JOIN payment e
ON p.cid=e.cid
Related
It's possible left join only one row without sub query?
I need to get product statistics and some of products have multiple groups.
Therefore, the amount of products is incorrect.
SELECT COUNT(p.id) AS total_product, SUM(p.price) AS total_price
FROM product p
LEFT JOIN attribute_group a ON
a.product_id = p.id
WHERE p.created_at >= "2018-01-01" AND (a.id = 1 OR a.id = 2)
GROUP BY p.id
LIMIT 0, 30;
product
id | price
1 | 100
2 | 150
3 | 250
attribute_group
id | product_id | title
1 | 1 | a1
2 | 1 | a2
3 | 2 | a3
4 | 3 | a4
Should be:
1| 100
But i get:
2 | 200
You appear to want all products or the counts/sum of them that have attributes of both 1 and 2. Here is one method:
SELECT COUNT(*) as num_products, SUM(p.price) as total_price
FROM product p
WHERE p.created_at >= '2018-01-01' AND
EXISTS (SELECT 1
FROM attribute_group ag
WHERE ag.product_id = p.id AND ag.id = 1
) AND
EXISTS (SELECT 1
FROM attribute_group ag
WHERE ag.product_id = p.id AND ag.id = 2
);
I have 3 tables like these:
product
product_id | name
1 | Pizza Margherita
2 | Pizza Salsiccia
3 | Pizza Marinara
filter_description
filter_id | name
1 | Mozzarella
2 | Pomodoro
3 | Salsiccia
product_filter
product_id | filter_id
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 2
I need to join 3 tables and make two queries, the first for all pizza without 'Mozzarella', and the second for all pizza with 'Mozzarella' AND 'Salsiccia'.
You could use below query for your criteria
For all pizza without 'Mozzarella'
select p.product_id, p.name
from product p
join product_filter pf using(product_id)
join filter_description fd using(filter_id)
group by p.product_id, p.name
having sum(fd.name = 'Mozzarella') = 0;
For all pizza with 'Mozzarella' AND 'Salsiccia'
select p.product_id, p.name
from product p
join product_filter pf using(product_id)
join filter_description fd using(filter_id)
group by p.product_id, p.name
having sum(fd.name = 'Mozzarella') = 1
and sum(fd.name = 'Salsiccia') = 1;
Demo
Variants with NOT IN and IN
-- all pizza without 'Mozzarella'
SELECT *
FROM product
WHERE product_id NOT IN(
SELECT DISTINCT pf.product_id
FROM product_filter pf
JOIN filter_description fd ON fd.filter_id=pf.filter_id
WHERE fd.name='Mozzarella'
)
-- all pizza with 'Mozzarella' AND 'Salsiccia'.
SELECT *
FROM product
WHERE product_id IN(
SELECT pf.product_id
FROM product_filter pf
JOIN filter_description fd ON fd.filter_id=pf.filter_id
WHERE fd.name IN('Mozzarella','Salsiccia') -- condition 1
GROUP BY pf.product_id
HAVING COUNT(fd.name)=2 -- condition 2
)
I have the following Tables :
Table : product
--------------------------
id_product | name_product
--------------------------
1 | p1
2 | p2
3 | p3
Table : number
-----------------------
imei | id_product
-----------------------
56789 | 1
56799 | 2
56713 | 3
Table : Operatio
----------------------
imei | date
------------------
56789 |31-07-2017
At last I want to get this result :
---------------------------------------
name_product | number_operation
---------------------------------------
p1 | 1
p2 | 0
p3 | 0
Thanks You
This will count the number of operations by product:
select name_product, sum(num_op)
from product p1
left join number n2
on n2.id_product = p1.id_product
left join
(
select imei, count(operation) as num_op
from Operation
group by imei
) x
on x.imei = n2.imei
group by name_product
For the number of products that have had an operation:
select name_product, count(distinct o3.imei)
from product p1
left join number n2
on n2.id_product = p1.id_product
left join Operation o3
on o3.imei = n2.imei
group by name_product
A possible solution :
SELECT name_product, COUNT(*)
FROM product p
LEFT JOIN number n ON n.id_product = p.id_product
LEFT JOIN operation o ON o.imei = n.imei
GROUP BY p.id_product
SELECT product.id_product,COUNT(number.id_product)
FROM product
INNER JOIN number ON product.id_product = number.id_product;
GROUP BY product.id_product
SELECT name_product, count (imei) c
FROM (SELECT name_product, o.imei
FROM (SELECT p.name_product, n.imei
FROM product p, "number" n
WHERE p.id_product = n.id_product) t
LEFT JOIN
Operatio o
ON t.imei = o.imei)
GROUP BY name_product
Try this code
This is my sql table structure:
Table1: details
|--id--|--id_user--|--price--|
| 1 | 1 | 10 |
| 2 | 2 | 15 |
| 3 | 1 | 25 |
| 4 | 3 | 30 |
| 5 | 3 | 7 |
------------------------------
Table2: users
|--id--|--id_country--|
| 1 | 1 |
| 2 | 2 |
| 3 | 0 |
-----------------------
Table3: country
|--id--|--country--|
| 1 | France |
| 2 | Italy |
--------------------
What I need is to get the SUM of price by country:
SELECT c.country, SUM(d.price) AS price
FROM details d
INNER JOIN users u ON u.id = d.id_user
INNER JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
I get this:
|--country--|--price--|
| France | 35 |
| Italy | 15 |
-----------------------
BUT I'd need to get this:
|--country--|--price--|
| France | 35 |
| Italy | 15 |
| Undefined | 37 |
-----------------------
where undefined would be if id_country=0. (I can't add to country table the id=0 or id=undefined, it will messed up other things). Right now I'm achieving this by two separate queries, the second one is:
SELECT SUM(d.price) as price
FROM details d
INNER JOIN users u ON u.id = d.id_user AND u.id_country=0
GROUP BY u.id_country
I'm thinking if... is it possible to do this in one query?
You need to use left join in this case:
SELECT c.country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
If you use INNER JOIN, you will only get results that exists in both tables.
To replace NULL with Undefined use:
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
One way to sort to get Undefined last is to add a Sortfield
SELECT A.Country,A.Price FROM (
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price, IFNULL(c.Country,'ZZZZZZZZ') AS Sort
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
) A
ORDER BY A.Sort
Edit: ORDER BY suggested in comments
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country IS NULL, c.country
Try below query.
SELECT
CASE
WHEN c.country is NULL THEN 'Undefined'
ELSE c.country
END as country
, SUM(d.price) AS price
FROM users u
left JOIN details d ON u.id = d.id_user
left JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
For Demo :
SqlfiddlE Demo :
Please let us know if you have any que.
I'm not sure I phrased the question correctly, so feel free to correct me. Here are the tables with their data:
product category category_product
------- -------- ----------------
id_product id_category active id_category id_product
1 1 1 1 1
2 2 1 2 1
3 3 0 1 2
4 0 2 2
3 2
3 3
4 3
I need to select only those products, which have all categories as inactive.
For example:
Product 1 is good, since it belongs to active categories (1, 2).
Product 2 is good, since it has at least one active category (1, 2; 3 - inactive)
Product 3 must be selected, since all its categories are inactive (3, 4).
I have the following query, which is obviously incorrect, since it selects both products: 2 and 3:
SELECT p.id_product
FROM product p
JOIN category_product cp
ON p.id_product = cp.id_product
JOIN category c
ON c.id_category = cp.id_category
WHERE
c.active = 0;
Here is the SQL Fiddle: http://sqlfiddle.com/#!2/909dd/2/0
How can I solve this?
This way you can select product without active category.
SELECT p.id_product
FROM product p
WHERE NOT EXISTS
(SELECT * FROM
category_product cp
INNER JOIN category c ON c.id_category = cp.id_category
WHERE p.id_product = cp.id_product AND c.active = 1);
SQL Fiddle
Consider the following:
SELECT p.*
, COUNT(*)
, SUM(c.active = 1) active
, SUM(c.active = 0) inactive
FROM product p
JOIN category_product cp
ON cp.id_product = p.id_product
JOIN category c
ON c.id_category = cp.id_category
GROUP
BY p.id_product;
+------------+----------+--------+----------+
| id_product | COUNT(*) | active | inactive |
+------------+----------+--------+----------+
| 1 | 2 | 2 | 0 |
| 2 | 3 | 2 | 1 |
| 3 | 2 | 0 | 2 |
+------------+----------+--------+----------+
http://sqlfiddle.com/#!2/909dd/55
The last part of this problem has been left as an exercise for the reader
This is what i get while trying...apologies if anything is wrong
set #count:=0;
select a.id_product,a.times from
(SELECT count(p.id_product)times, p.id_product, c.active,
if(c.active!=0, #count:=#count+1, #count:=0) x
From category_product cp
join product p
on (p.id_product = cp.id_product)
join category c
on(c.id_category = cp.id_category )
group by id_product )a
where a.x=0;