i have 4 tabels
drinks, opskrifter, ingredients and stock
the tables consist of
drinks
drink_id
name
beskriv
glas
image
alcohol
opskrifter
drink_id
ingredient_id
quantity
ingredients
ingredient_id
name
stock
ingredient_id
name
i want a query to select drinks that can be made in opskrifter of the ingredients in stock.
i have this working, but it only returns drink_id.
select o.drink_id
from opskrifter o
left join stock s on s.ingredient_id = o.ingredient_id
group by o.drink_id
having count(*) = count(s.ingredient_id)
I want it to return:
drink_id, name, beskriv, glas, image, alcohol
somebody help my on the way :-) thx
Basically you need to bring the drink table. I would just use a join for that, while turning the aggregate query to a subquery:
select d.*, o.cnt_ingredients
from drink d
inner join (
select o.drink_id, count(*) as cnt_ingredients
from opskrifter o
left join stock s on s.ingredient_id = o.ingredient_id
group by o.drink_id
having count(*) = count(s.ingredient_id)
) o on o.drink_id = d.drink_id
Just add them to the list after SELECT and to the GROUP BY.
SELECT o.drink_id,
o.name,
o.beskriv,
o.glas,
o.image,
o.alcohol
...
GROUP BY o.drink_id,
o.name,
o.beskriv,
o.glas,
o.image,
o.alcohol
...
If drink_id is a key, it might also be enough to list only drink_id in the GROUP BY clause.
I don't think your query does work, you should calculate the number of ingredients used and the number that exist and you could use a cte then join for example
DROP TABLE IF EXISTS drinks,OPSKRIFTER,ingredients,stock;
create table drinks
(drink_id int,
name varchar(3),
beskriv int,
glas int,
image varchar(10),
alcohol int
);
create table opskrifter
(drink_id int,
ingredient_id int,
quantity int
);
create table ingredients
(ingredient_id int,
name varchar(3)
);
create table stock
(ingredient_id int,
name varchar(3)
);
insert into drinks(drink_id,name) values (1,'n1'),(2,'n2');
insert into opskrifter values (1,1,10),(1,2,10),(2,1,20);
insert into stock values(1,'i1'),(2,'I2');
with cte as
(
select o.drink_id,count(*) cnt,(Select count(*) from stock) sn
from opskrifter o
group by o.drink_id having cnt = sn
)
select drinks.drink_id,drinks.name
from cte
join drinks on drinks.drink_id = cte.drink_id;
+----------+------+
| drink_id | name |
+----------+------+
| 1 | n1 |
+----------+------+
1 row in set (0.00 sec)
Related
CREATE TABLE Cart (
Id_cart INT NOT NULL,
Id_product VARCHAR(25)
);
CREATE TABLE product (
id_product VARCHAR(25),
id_vendor INT NOT NULL
);
CREATE TABLE Orders (
Id INT,
Id_cart INT NOT NULL,
status VARCHAR(25),
order_no VARCHAR(25),
id_vendor INT NOT NULL
);
-- data
INSERT INTO Cart
(Id_cart, id_product)
VALUES
(1, 'abc002'),
(1, 'abc003')
;
INSERT INTO product
(id_product, id_vendor)
VALUES
('abc002',2),
('abc003',3)
;
INSERT INTO Orders
(Id, Id_cart,status,order_no,id_vendor)
VALUES
(1, 1, 'pending','aaa001',2),
(2, 1, 'pending','aaa002',3)
This is my sql query used to display output
Select c.id_cart,order_no,id_product from orders as o
left join (SELECT * FROM cart) c using(id_cart) where id_product = 'abc002'
//
//output
id_cart order_no id_product
1 aaa001 abc002
1 aaa002 abc002
//
//expected output
id_cart order_no id_product
1 aaa001 abc002
I want it to show only the order_no which belong id_product (abc0002) instead of showing all the order_no with the same id_cart of id_product(abc0002).
How can i do this? Anything wrong with my query? thanks.
Oof. Owie. My bones.
First things first, for the love of things please keep it somewhat clean, there's so much wrong with query it hurts my eyes. I'm not even certain what it is you're trying to achieve truth be told. From what I can see you're not using left join properly. You also have no PKs, which could've made things easier. I'm also not sure what purpose cart is serving in this statement.
Try the below and please review how and why it works if that's what you're looking for:
SELECT o.id_cart, o.order_no, p.id_product FROM orders o
LEFT JOIN product p ON o.id_vendor = p.id_vendor
LEFT JOIN cart c ON p.id_product = c.id_product
WHERE p.id_product = 'abc002'
This is my sample data
-- schema
CREATE TABLE Cart (
Id_cart INT NOT NULL,
Id_product VARCHAR(25)
);
CREATE TABLE Orders (
Id INT,
Id_cart INT NOT NULL,
Id_vendor INT NOT NULL,
status VARCHAR(25),
order_no VARCHAR(25)
);
-- data
INSERT INTO Cart
(Id_cart, Id_product)
VALUES
(1, 'abc002'),
(1, 'abc003')
;
INSERT INTO Orders
(Id, Id_cart,Id_vendor,status,order_no)
VALUES
(1, 1,1, 'pending','aaa001'),
(2, 1,2, 'pending','aaa002')
;
I use this query to show record.
Select c.id_cart,order_no,id_product from cart as c
left join (SELECT id_cart,status,order_no FROM orders) o using(id_cart)
The result i get
id_cart order_no id_product
1 aaa002 abc002
1 aaa001 abc002
1 aaa002 abc003
1 aaa001 abc003
The result i expected
id_cart order_no id_product
1 aaa001 abc002
1 aaa002 abc003
Anything wrong with my query? How can i eliminate the duplicate record?
Let's say i added a column vendor_id to the orders table. Each order_no belong to one vendor and an id_cart will belong to many supplier. When i am trying to display my product, i want to display order_no and my id_product.
E.g. I have a cart belong to two order
an order belong to vendor A (1) and consist of product A and B.
an order belong to vendor B (2) and consist of product C and D.
During display the output should be
order_no | product_id
order1 | A
order1 | B
order2 | C
order2 | D
Now my problem is each order_no will be loop for each product_id. How can i overcome this?
You want to show cart products along with their orders. Carts contain products from different vendors for which exist separate orders. So join the product table to the cart in order to know the vendor and only then join the order table.
select
id_cart,
o.order_no,
id_product
from cart c
join product p using (id_product)
join orders o using (id_cart, id_vendor);
If you also want cart products for which no order has been written yet, make the orders join an outer join.
UPDATE: As you are reporting an issue with "Unknown column 'id_vendor' in 'from clause'", here is the query with ON clauses instead:
select
c.id_cart,
o.order_no,
c.id_product
from cart c
join product p on p.id_product = c.id_product
join orders o on o.id_cart = c.id_cart and o.id_vendor = p.id_vendor;
Simple add GROUP BY to your sql Query
SELECT c.id_cart,order_no,id_product FROM cart AS c
left join (SELECT id_cart,status,order_no FROM orders) o using(id_cart) GROUP BY o.order_no
Example :- http://sqlfiddle.com/#!9/b6b118/6/0
I have 4 tables:
Students with over 7000 records
Teachers with over 600 records
Universities with over 30 records
Lessons_Meta with over 10000 records
Table Students columns:
id | student_number | name
Table Teachers columns:
id | teacher_number | name
Table Universities columns:
id | name
Table Lessons_Meta columns:
id | lesson_code | lesson_name | student_id | teacher_id | university_id
My view is:
CREATE VIEW `view_lessons` AS
SELECT
*,
(SELECT `name` FROM `students` WHERE `students`.`id` = `lessons_meta`.`student_id` LIMIT 1) AS "student_name",
(SELECT `name` FROM `teachers` WHERE `teachers`.`id` = `lessons_meta`.`teacher_id` LIMIT 1) AS "teacher_name",
(SELECT `name` FROM `universities` WHERE `universities`.`id` = `lessons_meta`.`university_id` LIMIT 1) AS "university_name"
FROM `lessons_meta`
My query is:
SELECT * FROM `view_lessons` LIMIT 20
After 20 seconds, show this query completed! How can I decrease this time load?
You probably just need indexes. Start with the following indexes:
CREATE INDEX idx_students_id_name ON students(id, name);
CREATE INDEX idx_teachers_id_name ON teachers(id, name);
CREATE INDEX idx_universities_id_name ON universities(id, name);
Change your View to this
CREATE VIEW `view_lessons` AS
SELECT L.*, S.`name` AS student_name, T.`name` AS teacher_name, U.`name` AS university_name
FROM `lessons_meta` L
INNER JOIN `students` S ON S.`id` = L.`student_id`
INNER JOIN `teachers` T ON T.`id` = L.`teacher_id`
INNER JOIN `universities` U ON U.`id` = L.`university_id`
In the lessons_meta table, add indexes on student_id, teacher_id, university_id
On all tables, ensure that the id column is properly indexed, normally they should be unique/PK
In redshift for a provided dataset for a restaurant
Every Dish_id is being assigned to a category
So based on the distinct orders which are being palced
I need to find out for a provided primary dish what all other items went along with it
primary item (every distinct item of that restaurant will act as a primary dish once)
Currently i am able to do it for a single dish_id and getting its contribution
Select category_name,count(category_name) from (
Select order_id,dish_id,dish_name,category_id,category_name from abc
where order_id in (Select distinct order_id from abc where dish_name='Paneer_pizza' and restaurant_id=1)
group by order_id,dish_id,dish_name,category_id,category_name
order by category_name
)
group by category_name
Question's
How can i print Panner_pizza in the outer query along with category_name and count?
How can i pass all the dish_name present in that restaurant in inner query
and get the contribution for all the dishes along with count for all the categories?
Hard to tell exactly what you want...you might need two queries. But I think an inner query like this might help. This will filter the results to just the primary dish and restaurant that you are interested in and add the primary dish to each record in the order.
select a.order_id, primary_dish, dish_id, dish_name, category_id, category_name
from abc a
inner join (
Select distinct order_id, dish_name as primary_dish
from abc
where dish_name='Paneer_pizza' and restaurant_id=1
) b on b.order_id = a.order_id
where primary_dish != dish_name --optionally exclude the primary dish record
So count of other dish categories for the primary dish would be:
with dishes as (
select a.order_id, primary_dish, dish_id, dish_name, category_id, category_name
from abc a
inner join (
Select distinct order_id, dish_name as primary_dish
from abc
where dish_name='Paneer_pizza' and restaurant_id=1
) b on b.order_id = a.order_id
where primary_dish != dish_name --optionally exclude the primary dish record
)
select primary_dish, category_name, count(*) from dishes
group by primary_dish, category_name
I think this might be what you actually want. This gives all the dishes in the restaurant treating each as a primary dish and then gives dishes ordered with the primary, their category and the total number of orders placed that included the secondary dish:
with dishes as (
select a.order_id, primary_dish, dish_id, dish_name, category_id, category_name
from abc a
inner join (
Select distinct order_id, dish_name as primary_dish
from abc
where restaurant_id=1
) b on b.order_id = a.order_id
where primary_dish != dish_name --optionally exclude the primary dish record
)
select primary_dish, dish_name, category_name, count(*) from dishes
group by primary_dish, dish_name, category_name
I have two tables, one is Customer Detail and the other is Order Detail. Each time the Customer will order something it will store it in database. How can I find which customer orders and how many times they order and combine the customer name and orders?
CUSTOMER DETAIL:
ID NAME AGE COUNTRY
1 AAA 22 US
2 BBB 26 UK
3 CCC 25 TN
ORDER DETAIL:
ID ITEMS PRICE QUANTITY
1 APPLE 5
1 ORANGE 6
1 MANGO 4
Customer AAA has many orders.
EXPECTED RESULT:
CUSTOMERDETAIL ORDERDETAIL
AAA (HOW MANY TIMES HE ORDER AND ORDER DETAILS)
Create Table Customer (CustomerId int identity(1,1),Name varchar(20))
Create Table OrderDetail(OrderDetailId int identity(1,1), CustomerId int, Item varchar(20), Quantity int)
Insert into Customer values('AAA')
Insert into Customer values('BBB')
Insert into Customer values('CCC')
Insert into OrderDetail values(1,'Apple',10)
Insert into OrderDetail values(1,'Banana',10)
Insert into OrderDetail values(1,'Mango',10)
select y.total, x.Item,x.quantity from
(
select c.customerId as customerId, d.Item, d.quantity from customer c inner join orderdetail d
on c.customerId = d.customerId
)x
inner join
(
select customerid, COUNT(customerId)as total from orderdetail group by customerId
)y
on x.customerId = y.customerId
Suppose you have the schema like this:
Customer table (customer)
ID (Customer Id) int primary key
Name varchar(100)
Order Table (orders)
ID (Order ID) int
cusotmer_id (reference id of customer table primary key-ID) int
quality int
price float
First Count of Order against eash customer:
select count(o.customer_id) as total_order, c.* from customer c left join orders o on c.ID = o.customer_id
Orders listing against a single customer:
select c.*, o.* from customer c inner join orders o on c.ID = o.customer_id where c.ID = 1
I hope this will help you.
The following query gives what i expect.
SELECT name,items,price FROM customerdetail INNER JOIN orderdetail ON customerdetail .sno=orderdetail .id WHERE id=1 ;