Mysql select in 1 table, update 2 table - mysql

There are three tables:
shop_product_skus - a table for the item 1 product ( 1 to many )
shop_product_skus(id,product_id,sku,sort,name,image_id,price,primary_price,purchase_price,compare_price,count,available,dimension_id,file_name,file_size,file_description,virtual)
shop_product_stocks - a table of how many products in different warehouses
shop_product_stocks(sku_id, stock_id, product_id, count)
shop_product_ostatki - this is a temporary table with the amount of product , price and sku from one warehouse , for example stock_id = 1 ( 1 is updated every 30 minutes)
shop_product_ostatki (id, sku, count, price)
Foreign Key Relations
shop_product_skus.product_id = shop_product_stocks.product_id
shop_product_skus.sku = shop_product_ostatki.sku
shop_product_skus.id = shop_product_stocks.sku_id
Now I need to update data from shop_product_ostatki
In table shop_product_skus
update shop_product_skus.price = shop_product_ostatki.price * 1.07,
shop_product_skus.purchase_price = shop_product_ostatki.price * 0.7
where shop_product_skus.sku = shop_product_ostatki.sku
In table shop_product_stocks
update if there is no prompt to add
shop_product_stocks.count = shop_product_ostatki.count,
shop_product_stocks.price = shop_product_ostatki.price * 1.07
where shop_product_skus.sku = shop_product_ostatki.sku
and shop_product_skus.id = shop_product_stocks.sku_id
Probably explained a little confusing , I do it all in one query.
For 4 days I struggle with this issue, search by stackoverflow enjoyed similar questions not found :(
ps sorry for my english
UPDATE
http://sqlfiddle.com/#!2/90f67
UPDATE
I'm try this, it's not worked
INSERT INTO shop_product_stocks (sku_id ,stock_id ,product_id ,'count')
(SELECT id.b ,product_id.b ,sku.b ,sort.b ,name.b ,image_id.b, price.b ,primary_price.b ,purchase_price.b ,available.b FROM shop_product_skus b
LEFT JOIN shop_product_ostatki c ON c.sku = b.sku
LEFT JOIN shop_product_skus a ON a.sku = c.sku
WHERE shop_product_stocks.stock_id = 1
)
ON DUPLICATE KEY UPDATE
'count' = 'count'.c
UPDATE
error in select
SELECT * FROM shop_product_skus AS b
LEFT JOIN shop_product_ostatki_sander AS c ON c.sku = b.sku
LEFT JOIN shop_product_stocks AS a ON a.sku_id = b.id
WHERE a.stock_id = 1
but all expr not worked

Related

Get products without sales for last 7day

I have two tables products and user_sales. I need to get the products which have 0 sales for the last 7 days.
I tried some code which I found in stack overflow with the "HAVING" statement but I found out if I put a limit of 12 products than it doesnt works.
Can anoyone please help ?
table products
id | title | price | images | description
table user_sales
id | product_id | sale_date | user_owner
Well that was the simplified version of the tables. The actual query looks somehow like this.
SELECT `product_store`.`friendly_name` AS `store_friendly_name`,
`api_keys`.`key_data` AS `api_data`,
`ep`.*,
`supplier_store`.`icon` AS `supplier_store_icon`,
`supplier_store`.`internal_name` AS `supplier_store_internal_name`,
`supplier_store`.`friendly_name` AS `supplier_store_friendly_name`,
`supplier_store`.`amazon_type_product` AS
`supplier_store_amazon_type_product`,
`supplier_store`.`handler` AS `supplier_store_handler`,
`sp`.`extra_data` AS `sp_extra_data`,
`sp`.`id` AS `sp_id`,
`sp`.`remote_id` AS `sp_remote_id`,
`sp`.`url` AS `sp_url`,
`sp`.`price` AS `sp_price`,
`sp`.`stock` AS `sp_stock`,
`sp`.`picture` AS `sp_picture`,
`sp`.`store_id` AS `sp_store_id`,
Count(us.date) AS sale_date
FROM `products` `ep`
LEFT JOIN `stores` `product_store`
ON `ep`.`store_id` = `product_store`.`id`
LEFT JOIN `api_keys`
ON `api_keys`.`id` = `ep`.`link_key`
LEFT JOIN `products` `sp`
ON `ep`.`linked_to` = `sp`.`id`
LEFT JOIN `stores` `supplier_store`
ON `supplier_store`.`id` = `sp`.`store_id`
RIGHT JOIN `user_sales` `us`
ON `ep`.`remote_id` = `us`.`remote_id`
WHERE `ep`.`user_owner` = '3992'
AND `ep`.`expired` = 0
AND `us`.`user_id` = '3992'
AND us.date > "2019-02-09 14:21:34"
AND us.date < "2019-05-10 14:21:34"
AND `ep`.`store_id` = 3
GROUP BY `ep`.`id`
HAVING `sale_date` < 1
ORDER BY `ep`.`id` DESC
LIMIT 15
You want to ensure that no sales exist for the product in the last seven days. Use NOT EXISTS for that.
From your query I take it that you want to restrict this to products belonging to user_owner 3992 and to sales of the same user.
WHERE ep.user_owner = 3992
AND ep.expired = 0
AND ep.store_id = 3
AND NOT EXISTS
(
SELECT *
FROM user_sales us
WHERE us.user_id = ep.user_owner
AND us.date > current_date - interval 7 day
)
The complete query:
SELECT product_store.friendly_name AS store_friendly_name,
api_keys.key_data AS api_data,
ep.*,
supplier_store.icon AS supplier_store_icon,
supplier_store.internal_name AS supplier_store_internal_name,
supplier_store.friendly_name AS supplier_store_friendly_name,
supplier_store.amazon_type_product AS
supplier_store_amazon_type_product,
supplier_store.handler AS supplier_store_handler,
sp.extra_data AS sp_extra_data,
sp.id AS sp_id,
sp.remote_id AS sp_remote_id,
sp.url AS sp_url,
sp.price AS sp_price,
sp.stock AS sp_stock,
sp.picture AS sp_picture,
sp.store_id AS sp_store_id
FROM products ep
LEFT JOIN stores product_store ON ep.store_id = product_store.id
LEFT JOIN api_keys ON api_keys.id = ep.link_key
LEFT JOIN products sp ON ep.linked_to = sp.id
LEFT JOIN stores supplier_store ON supplier_store.id = sp.store_id
WHERE ep.user_owner = 3992
AND ep.expired = 0
AND ep.store_id = 3
AND NOT EXISTS
(
SELECT *
FROM user_sales us
WHERE us.user_id = ep.user_owner
AND us.date > current_date - interval 7 day
)
ORDER BY ep.id DESC;

How to update a table with subquery using data from the same table

I would like to update a column from a table, and the data i want to put in is the result of a mathematical operation using subquerys that references the update table.
The problem is I want to update every row using data from the same row in the mathematical operation mentioned above.
Here's the example:
UPDATE licenses as lic
SET lic.numSessions =
(
select difference from
(select
(
select (p.numSessions * p.numMonth) as num from products p
inner join licenses l on p.idProduct = l.idProduct and l.idpatient = lic.idPatient and l.currentLicense = 1
)
-
(
SELECT COUNT(distinct s.idSession) as num
FROM sessions s
WHERE s.idPatient = lic.idPatient
AND s.dateValue >= (select l.dateCreated from licenses l where l.idPatient = lic.idPatient and l.currentLicense = 1) AND s.status = 2
)
as difference
)
x
);
EDIT:
Example of what i want:
Every row of 'licenses' has a 'idPatient'. Let's call it 'X'.
I want to see how many sessions X has done (for example 10) and then substract this number from the total number of sessions of 'X's' product have (for example 50). So the result in the update for X will be: 50 - 10 = 40.
The subqueries alone work perfectly, I'have the value of 50, then the value of 10, and then when I try to substract I have the value 40 as a column named 'difference'.
The problem I've got is that the query can't recognize the value 'lic.idPatient' inside the first subquery in the substract operation:
/* SQL Error (1054): Unknown column 'lic.idPatient' in 'on clause' */
Thanks in advance and sorry for my writing, I'm not native English.
You have to write query like this
UPDATE licenses AS licNew
SET licNew.numSessions =
(
SELECT x.difference FROM
((SELECT
(
SELECT (p.numSessions * p.numMonth) AS num FROM products p
INNER JOIN licenses l ON p.idProduct = l.idProduct AND l.idpatient = lic.idPatient AND l.currentLicense = 1
)
-
(
SELECT COUNT(DISTINCT s.idSession) AS num
FROM sessions s
WHERE s.idPatient = 6361
AND s.dateValue >= (SELECT l.dateCreated FROM licenses l WHERE l.idPatient = 6361 AND l.currentLicense = 1) AND s.status = 2
))
AS difference, lic.idPatient
FROM licenses lic
)
X WHERE licNew.idPatient = x.idPatient
);
In general, you cannot modify a table and select from the same table in a subquery.
Please refer this link.

how to optimize mysql query with inner join

select id from customer_details where store_client_id = 2
And
id NOT IN (select customer_detail_id from orders
where store_client_id = 2 and total_spent > 100 GROUP BY customer_detail_id )
Or
id IN (select tcd.id from property_details as pd, customer_details as tcd
where pd.store_client_id = 2 and pd.customer_detail_id = tcd.customer_id and pd.property_key = 'Accepts Marketing'
and pd.property_value = 'no')
And
id IN (select customer_detail_id from orders
where store_client_id = 2 GROUP BY customer_detail_id HAVING count(customer_detail_id) > 0 )
Or
id IN (select tor.customer_detail_id from ordered_products as top, orders as tor
where tor.id = top.order_id and tor.store_client_id = 2
GROUP BY tor.customer_detail_id having sum(top.price) = 1)`
I have this mysql query with inner join so when it run in mysql server it slow down what is the issue cant find.
But after 4-5 minutes it return 15 000 records. This records is not an issue may be.
In some tutorial suggest to use Inner join, Left join,...
But I don't know how to convert this query in Join clause.
Any help will be appreciated. Thanks in advance.
First of all please read relational model and optimizing select statements.

Counting entry in a column MySQL and display counts

I would want to count entries in a column and display the count beside it.
However, I'm clueless on how can I do it.
Desired output:
arrangement_number tray_no rl_type flag(count of occurrence)
------------------ ------- ---- ----
2774818 381001 R 3
2774818 381001 R 3
2774818 381001 L 3
2778470 405128 R 1
2779702 265265 R 2
2779702 265265 R 2
I'm currently trying queries using #variables but I still cant get it right.
each row are unique and I need them not to be grouped.
Update: Expanded Table added source code
Note: I'm currently joining 5 tables now
Actual Query:
SELECT
log.arrangement_number,
header.tray_number,
detail.rl_type,
-- some more fields here
FROM
log
INNER JOIN
header ON log.arrangement_number = header.rxarrangement_number
AND log.production_place_code = header.production_place_code
INNER JOIN
detail ON log.arrangement_number = detail.rxarrangement_number
AND log.production_place_code = detail.production_place_code
INNER JOIN
deliveryperiod ON log.arrangement_number = deliveryperiod.arrangement_number
AND log.production_place_code = deliveryperiod.production_place_code
AND detail.rl_type = deliveryperiod.rl_type
INNER JOIN
calc ON calc.arrangement_number = log.arrangement_number
AND calc.production_place_code = log.production_place_code
AND deliveryperiod.rl_type = calc.rl_type
AND detail.rl_type = calc.rl_type
WHERE
header.status_code IN ('20' , '21')
AND log.process_code = '12'
AND deliveryperiod.process_code_current = '12'
AND deliveryperiod.sub_process_code_current IN ('100' , '105')
AND lot_number = '120131'
ORDER BY log.lot_number , log.sequence_number , deliveryperiod.rl_type DESC
SELECT t1.tray_no,
t2.flag
FROM yourTable
INNER JOIN
(
SELECT tray_no, COUNT(*) AS flag
FROM yourTable
GROUP BY tray_no
) t2
ON t1.tray_no = t2.tray_no
try this...
SELECT tray_no, COUNT(*) 'flag'
FROM table1
GROUP BY tray_no

Is there a way to optimize this update query?

I have a master table called "parent" and a related table called "childs"
Now I run a query against the master table to update some values with the sum from the child table like this.
UPDATE master m SET
quantity1 = (SELECT SUM(quantity1) FROM childs c WHERE c.master_id = m.id),
quantity2 = (SELECT SUM(quantity2) FROM childs c WHERE c.master_id = m.id),
count = (SELECT COUNT(*) FROM childs c WHERE c.master_id = m.id)
WHERE master_id = 666;
Which works as expected but is not a good style because I basically make multiple SELECT querys on the same result. Is there a way to optimize that? (Making a query first and storing the values is not an option.
I tried this:
UPDATE master m SET (quantity1, quantity2, count) = (
SELECT SUM(quantity1), SUM(quantity2), COUNT(*)
FROM childs c WHERE c.master_id = m.id
) WHERE master_id = 666;
but that doesn't work.
Update: Here is the solution, thanks to everbody:
You can do something like this:
UPDATE master m
INNER JOIN childs c ON m.master_id = c.master_id
SET master.quantity1 = c.quantity1,
master.count = 1
If you have only one child record at a time. However if you want to use a group function like SUM() in the joined table that doesn't work. Either you get a "Invalid use of group function" if you leave the "group by" part or a "You have an error in your sql syntax if you use "GROUP BY c.master_id"
-- This doesnt work :(
UPDATE master m
INNER JOIN childs c ON m.master_id = c.master_id
SET master.quantity1 = SUM(c.quantity1),
master.count = COUNT(c.*)
GROUP by c.master_id
The solution is to use JOIN with a subquery:
UPDATE master m
INNER JOIN
(
SELECT master_id,
SUM(quantity1) as quantity1,
COUNT(*) as count
FROM childs c
GROUP BY master_id
) c
ON c.master_id = m.master_id
SET m.quantity1 = c.quantity1,
m.count = c.count
WHERE m.master_id = 666;
But since this pulls every row from the childtable the overhead would likely be bigger than using more subqueries like in the original sql. So you should add a WHERE clause to the joined table to get only the rows you need.
Another interesting approach is this syntax, which does the same as the JOIN with the WHERE clause but you should only use if if you want to update all rows with the same values and your subquery only returns one row, since the result from the subquery gets appended to the result and can be used like any column.
UPDATE master m,
(
SELECT SUM(c.quantity1) as sum_of_quantity,
COUNT(*) as rowcount FROM child c WHERE c.master_id = 666
) as c
SET m.quantity1 = c.sum_of_quantity,
m.count = c.rowcount
WHERE m.master_id = 666;
Rewriting Lieven's solution to MySQL:
UPDATE master m
JOIN (
SELECT master_id
, SUM(quantity1) as quantity1
, SUM(quantity2) as quantity2
, COUNT(*) as count
FROM childs c
GROUP BY
master_id
) c
ON c.master_id = m.master_id
SET
m.quantity1 = c.quantity1
,m.quantity2 = c.quantity2
,m.count = c.count
WHERE m.master_id = 666;
I don't know if it is allowed in MySQL, but SQL Server allows you to use the result of a select in an update.
UPDATE master m SET
quantity1 = c.quantity1
, quantity2 = c.quantity2
, count = c.count
FROM master m
INNER JOIN (
SELECT master_id
, quantity1 = SUM(quantity1)
, quantity2 = SUM(quantity2)
, count = COUNT(*)
FROM childs c
WHERE master_id = 666
GROUP BY
master_id
) c ON c.master_id = m.master_id
You could select your data into a temporary table, and then update using that data.
If you also want to insert "new" data in the same roundtrip, look into INSERT INTO ... SELECT FROM ... ON DUPLICATE KEY UPDATE ...
If you already are doing inserts if row doesn't exist, then that would be redundant with this example.
example:
INSERT INTO master m (id, quantity1, quantity2, count)
SELECT master_id, SUM(quantity1) q1, SUM(quantity2) q1, COUNT(*) c
FROM childs
GROUP BY master_id
ON DUPLICATE KEY UPDATE
m.quantity1 = q1,
m.quantity2 = q2,
m.count = c
NOTE! This is untested code, but I think it should be possible to backreference the select result in the UPDATE.
Syntax reference: http://dev.mysql.com/doc/refman/5.0/en/insert.html