I have orders table where i show information about order number, products, and customer.
I need to show list of product names and their qty in column products separated or in new row like below in table:
Expected result
id | order_number | customer | address | total | products
------------------------------------------------------------------------------------
1 | OR00123 | Tom Helks | Test 221 | 1233,2 | 1x iphone
| 2x samsung
| 3x someproduct
Order table
id | order_number | customer_id | total | status_id
------------------------------------------------------------------------------------
1 | OR00123 | 1 | 1233,2 | 1
OrderProducts table
id | order_id | product_id | qty |
------------------------------------------------------
1 | 1 | 5 | 1 |
2 | 1 | 2 | 2 |
3 | 1 | 6 | 3 |
Product table
id | name | price
----------------------------------------
5 | iphone | 1231
2 | samsung | 2322
6 | someproduct | 432
What i try.
I get above expected result but only dont do subquery for listing products and qty for order.
SELECT
order.number,
customer.name,
customer.adress,
SUM(order_products.qty * product.price) as total,
# subquery here
(
SELECT p.name FROM products p WHERE order_products.product_id = p.id
) as products
FROM.orders as order
INNER JOIN customer on customer.customer_id= customer.id
INNER JOIN order_products on order.id = order_products.order_id
ORDER BY dok.created_at;
My imagination stopped and I believe that the problem is in the sub-query, but I can't see it at the moment.
Thanks
You need to join all tables and GROUP BY the unique values.
The GROUP_CONCAT has to be used with then CONCAT of the wanted values
CREATE TABLE orders
(`id` int, `order_number` varchar(7), `customer_id` int, `total` varchar(6), `status_id` int)
;
INSERT INTO orders
(`id`, `order_number`, `customer_id`, `total`, `status_id`)
VALUES
(1, 'OR00123', 1, '1233,2', 1)
;
CREATE TABLE orders_product
(`id` int, `order_id` int, `product_id` int, `qty` int)
;
INSERT INTO orders_product
(`id`, `order_id`, `product_id`, `qty`)
VALUES
(1, 1, 5, 1),
(2, 1, 2, 2),
(3, 1, 6, 3)
;)
Records: 3 Duplicates: 0 Warnings: 0
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
CREATE TABLE product
(`id` int, `name` varchar(11), `price` int)
;
INSERT INTO product
(`id`, `name`, `price`)
VALUES
(5, 'iphone', 1231),
(2, 'samsung', 2322),
(6, 'someproduct', 432)
;
Records: 3 Duplicates: 0 Warnings: 0
SELECT
order_number, `customer_id`, `total`,GROUP_CONCAT(CONCAT( op.`qty`,'x ',p.`name`) SEPARATOR ' ') products
FROM orders o
JOIN orders_product op ON o.`id` = op.`order_id`
JOIN product p ON op.`product_id` = p.`id`
GROUP BY order_number, `customer_id`, `total`
order_number
customer_id
total
products
OR00123
1
1233,2
1x iphone 2x samsung 3x someproduct
fiddle
Related
We have a table in which we have the product ID, the price, and the shop ID.
the key is on the couple (product-id/shop-id) so we can have twice the same product in the same shop.
table item_price
Product_ID | Shop_ID | Price
1 | 2 | 25.99
1 | 3 | 40.00
1 | 1 | 10.00
2 | 9 | 32.00
3 | 2 | 78.00
and a table Item_reference which contains the Product_name, product_id and the retail_price_eur
Item reference
product_title | product_id | retail_price_eur
product_1 | 1 | 19.99
product_2 | 2 | 29.99
product_3 | 3 | 79.99
My goal is to select the product 1, for which the discount is the bigger with the following request:
SELECT DISTINCT t1.product_id
, t2.retail_price_eur
, t2.product_title
, t1.price, CEIL ((t1.price-t2.retail_price_eur)/t2.retail_price_eur*100) AS product_discount
FROM item_price AS t1
JOIN item_reference AS t2
ON t1.product_id = t2.product_id
WHERE t1.product_id = 1
AND NOT retail_price_eur = 0
ORDER
BY product_discount DESC
so, I have a couple of issue:
Issue 1)
Even tho I put DISTINCT, I have duplicates of the same product_id...
(but if i only ask for "SELECT DISTINCT t1.product_id" without any other field from t1 i do not have duplicates). So I have an issue I do not understand..
Issue 2)
I do not know how to integrate the code allowing to select the smaller Minimum Discount.
I would assume something along the line of
"WHERE NOT retail_price_eur = 0 AND MIN(product_discount)"...
but this is not the correct answer and i do not know how to put it in.
PS: I use "min()" on product discount, as in some cases, the % of variation might be positive if the shop price is superior to the retail price.
here are the command to create the example:
CREATE TABLE evilbrick.item_price ( product_id INT NOT NULL , shop_id INT NOT NULL , price FLOAT NOT NULL ) ENGINE = MyISAM;"
CREATE TABLE evilbrick.item_reference ( product_title VARCHAR (10) NOT NULL , product_id INT NOT NULL , retail_price_eur FLOAT NOT NULL ) ENGINE = MyISAM;
INSERT INTO item_price (product_id, shop_id, price) VALUES (1, 2, 25.99)
INSERT INTO item_price (product_id, shop_id, price) VALUES (1, 3, 40)
INSERT INTO item_price (product_id, shop_id, price) VALUES (1, 1, 10)
INSERT INTO item_reference (product_title, product_id, retail_price_eur) VALUES ('product_1', 1, 19.99)
Below are two mysql tables. I want to check if the two people are in teams from Table: Teams and then getting their name and email from Table: Registration. I am having a hard time writing a mysql query for it.
Table: Registration
id: 1 name:jason email:jason#xyz.com
id: 2 name:kim email:kim#xyz.com
id: 3 name:tim email:tim#xyz.com
Table:Teams
team_id: 1 person1Id: 1 person2Id: 2
team_id: 2 person1Id: 1 person2Id: 3
You have to join the registration table twice and give them a unique alias
Schema (MySQL v8.0)
CREATE TABLE Teams (
`team_id` INTEGER,
`person1Id` VARCHAR(9),
`person2Id` INTEGER
);
INSERT INTO Teams
(`team_id`, `person1Id`, `person2Id`)
VALUES
('1', '1', '2'),
('1', '1', '3');
CREATE TABLE Registration (
`id` INTEGER,
`name` VARCHAR(5),
`email` VARCHAR(13)
);
INSERT INTO Registration
(`id`, `name`, `email`)
VALUES
('1', 'jason', 'jason#xyz.com'),
('2', 'kim', 'kim#xyz.com'),
('3','tim','tim#xyz.com');
Query #1
SELECT
t.team_id,r1.name,r1.email,r2.name,r2.email
FROM Teams t
INNER JOIN Registration r1 ON t.person1Id = r1.id
INNER JOIN Registration r2 ON t.person2Id = r2.id;
| team_id | name | email | name | email |
| ------- | ----- | ------------- | ---- | ----------- |
| 1 | jason | jason#xyz.com | kim | kim#xyz.com |
| 1 | jason | jason#xyz.com | tim | tim#xyz.com |
View on DB Fiddle
you can select both ids from Teams table and use in clause to get name and email from Registration table as
select name, email from Registration where id in(select person1Id, person2Id from Teams where team_id=1)
I have two tables in the following structure:
sales
|date |time | name | total |
|2017-04-01 |10:23:59 | aaa | 100 |
|2017-04-01 |10:23:59 | aaa | 150 |
|2017-04-01 |11:33:30 | bbb | 200 |
|2017-04-01 |11:33:30 | bbb | 120 |
|2017-04-02 |10:50:59 | aaa | 70 |
|2017-04-02 |10:30:59 | bbb | 35 |
payment
|date |time | name | amount |
|2017-04-01 |10:23:59 | aaa | 300 |
|2017-04-01 |11:33:30 | bbb | 400 |
|2017-04-02 |10:50:59 | aaa | 425 |
|2017-04-02 |10:30:59 | bbb | 600 |
Terms
sales.time = payment.time
where date = 2017-04-01
sum(sales.total) and sum(payment.amount)
group by time
i want this result
|date |time | name | sum(total) | sum(amount)|
|2017-04-01 |13:23:59 | aaa | 250 | 300 |
|2017-04-01 |12:33:30 | bbb | 320 | 400 |
Table structure
CREATE TABLE `payment` (`id` int(5) NOT NULL,`date` date NOT NULL,`time` time NOT NULL,`name` varchar(10) NOT NULL,`amount` varchar(10) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
INSERT INTO `payment` (`id`, `date`, `time`, `name`, `amount`) VALUES(3, '2017-04-01', '10:23:59', 'aaa', '300'),(4, '2017-04-01', '11:33:30', 'bbb', '400'),(5, '2017-04-02', '10:50:59', 'aaa', '425'),(6, '2017-04-02', '10:30:59', 'bbb', '600');
CREATE TABLE `sales` ( `id` int(5) NOT NULL,`date` date NOT NULL,`time` time NOT NULL,`name` varchar(10) NOT NULL,`total` int(10) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `sales` (`id`, `date`, `time`, `name`, `total`) VALUES(1, '2017-04-01', '10:23:59', 'aaa', 100),(2, '2017-04-01', '10:23:59', 'aaa', 150),(3, '2017-04-01', '11:33:30', 'bbb', 200),(4, '2017-04-01', '11:33:30', 'bbb', 120),(5, '2017-04-02', '10:50:59', 'aaa', 70),(6, '2017-04-02', '10:50:59', 'bbb', 35);
ALTER TABLE `payment` ADD PRIMARY KEY (`id`);
ALTER TABLE `sales` ADD PRIMARY KEY (`id`);
ALTER TABLE `payment` MODIFY `id` int(5) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
ALTER TABLE `sales` MODIFY `id` int(5) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
Query
SELECT sales.time,sales.name,
SUM(sales.total),SUM(payment.amount)
FROM sales,payment
WHERE sales.time=payment.time
and sales.date like '2017-04-01%'
GROUP BY sales.time
ORDER BY sales.time;
Result is
10:23:59 aaa 250 600
11:33:30 bbb 320 800
You are multiplying the payments amount with the number of sales records, because you are joining all payments records with all sales records before summing up the amounts.
Aggregate first, and only join then.
In case there can always only be one payments record per date, time and name:
select p.name, p.time, p.name, s.sales_total, p.amount
from payments p
join
(
select date, time, name, sum(total) as total
from sales
group by date, time, name
) s
on s.date = p.date and s.time = p.time and s.name = p.name
where p.date = date '2017-04-01';
Otherwise:
select p.name, p.time, p.name, s.total, p.amount
(
select date, time, name, sum(amount) as amount
from payments
group by date, time, name
) p
join
(
select date, time, name, sum(total) as total
from sales
group by date, time, name
) s
on s.date = p.date and s.time = p.time and s.name = p.name
where p.date = date '2017-04-01';
I have the following tables
1) discounts
+--------------------------------------------+
| ID discount_description discount_type |
+--------------------------------------------+
| 17 20% off PERCENT |
| 19 Citric ABSOLUTE |
+--------------------------------------------+
Table 2 - Products Included
+------+--------------+------------------+
| ID | discount_id | product_id |
+------+--------------+------------------+
| 2 | 17 | 52238403 |
| 3 | 17 | 52238409 |
| 4 | 19 | 52238408 |
+------+--------------+------------------+
Table 3 - Products Excluded
+---------------------------------+---------------+
| ID discount_id | product_id |
+---------------------------------+---------------+
| 2 17 | 52238411 |
| 3 17 | 52238408 |
+---------------------------------+---------------+
I need the query to fetch all the discounts based on product ID's from included table and excluded table. And it should also include the rows from discounts which is not present in products included/excluded table.
Below is a sample one to fetch discounts based on products 52238408,52238403.
SELECT
discounts.id as ID1,
discount_products.product_id as p1,
exclude_discount_products.product_id as p2
FROM discounts
LEFT JOIN `discount_products` ON 1=1
AND discounts.id = discount_products.discount_id
LEFT JOIN `exclude_discount_products` ON 1=1
AND discounts.id = exclude_discount_products.discount_id
WHERE discount_products.product_id IN (52238408,52238403)
AND exclude_discount_products.product_id NOT IN (52238408,52238403)
The query is just a basic version and i am pretty sure it's incorrect. But basically i wanted to check both the tables for product ID.
I am suppose to get discount 19 as the output since products excluded has 52238408, So 17 should ignored. But it gives 17 instead. Not sure what i am missing, any help is much appreciated.
Thanks
Not sure if you want this you didnt include the expected output.
Create table/insert data
CREATE TABLE discounts
(`ID` INT, `discount_description` VARCHAR(7), `discount_type` VARCHAR(8))
;
INSERT INTO discounts
(`ID`, `discount_description`, `discount_type`)
VALUES
(17, '20% off', 'PERCENT'),
(19, 'Citric', 'ABSOLUTE')
;
CREATE TABLE discount_products
(`ID` INT, `discount_id` INT, `product_id` INT)
;
INSERT INTO discount_products
(`ID`, `discount_id`, `product_id`)
VALUES
(2, 17, 52238403),
(3, 17, 52238409),
(4, 19, 52238408)
;
CREATE TABLE exclude_discount_products
(`ID` INT, `discount_id` INT, `product_id` INT)
;
INSERT INTO exclude_discount_products
(`ID`, `discount_id`, `product_id`)
VALUES
(2, 17, 52238411),
(3, 17, 52238408)
;
Query
SELECT
discounts.id AS ID1
, product_id AS p1
, (
# SELECT matching product_id FROM exclude_discount_products based on product_id (checks excludes)
SELECT
product_id
FROM
exclude_discount_products
WHERE
product_id = discount_products_NOT_IN_exclude_discount_products.product_id
)
AS p2
FROM (
# SELECT all discount_products that dont have the same discount_id, product_id as in exclude_discount_products
SELECT
*
FROM
discount_products
WHERE (
discount_id
, product_id
)
NOT IN (
SELECT
discount_id
, product_id
FROM
exclude_discount_products
)
)
AS
discount_products_NOT_IN_exclude_discount_products
INNER JOIN
discounts
ON
discount_products_NOT_IN_exclude_discount_products.discount_id = discounts.id
WHERE
product_id IN(
52238408
, 52238403
)
Result
ID1 p1 p2
------ -------- ----------
17 52238403 (NULL)
19 52238408 52238408
I have a table with attributes to a product:
product_attributes
+------------+--------------+-------------+------+
| product_id | attribute_id | language_id | text |
+------------+--------------+-------------+------+
| 1 | 2 | 2 | bla |
| 1 | 2 | 3 | blo |
| 1 | 3 | 2 | foo |
| 1 | 4 | 3 | bar |
+------------+--------------+-------------+------+
and I have another table called product with multiple product_ids that do not exist in the product_attributes table.
I would like to copy all data from product_attributes where product_id = 1 and insert them for ALL the ids in the product table.
This is what I had so far but it does not work.
INSERT INTO `product_attribute`(`product_id`, `attribute_id`, `language_id`, `text`) SELECT (SELECT 'product_id' FROM `product`), `attribute_id`, `language_id`, `text` FROM `product_attribute` WHERE `product_id` = '1';
It says the subquery returns more than 1 row (which it does, that's the point), I just don't know how to solve this with 2 subsets.
use cross join :
[1] solution :
INSERT INTO `product_attributes`(`product_id`, `attribute_id`,`language_id`, `text`)
select product_id,v.attribute_id,v.language_id,v.text
from product
cross join (SELECT attribute_id, language_id, text
FROM product_attributes
WHERE product_id = '1') v ;
[2] solution :
INSERT INTO `product_attributes`(`product_id`, `attribute_id`,`language_id`, `text`)
select b.product_id,`attribute_id`, `language_id`, `text`
from product_attributes a
CROSS join product b
use above sql query it is perfect and it has no error.
your sql :
INSERT INTO `product_attribute`(`product_id`, `attribute_id`, `language_id`, `text`)
SELECT (SELECT 'product_id' FROM product), attribute_id, language_id, text
FROM product_attribute
WHERE product_id = '1';
Here,in your sql (SELECT 'product_id' FROM product) returns
more than one value it is not possible in co-related sql.
when inner query behaves as a field then at a time it has only one value .
(SELECT 'product_id' FROM `product`)
In this query should be return more than one row.
I think this query should be not required.