How to update quantity referencing another table php/mysql - mysql

I'm a bit of a noob and I'm sure this is fairly simple but I've tried different things and I can't get my head around it.
I have a product table that contains a category id and I want to set the quantity to 0 which is stored in another table.
This is the last thing I tried:
function wipeprod(){
UPDATE stock_available
INNER JOIN
product stock_available
ON
(
product.id_category_default != 3
OR
product.id_category_default != 10
OR
product.id_category_default != 943
)
SET
stock_available.quantity = 0;
}
Thanks in advance.

I suspect that you want to set column quantity in table stock_available to 0 for products that are not in categories 3, 10, and 943.
If so, you can use the update ... join syntax as follows:
update stock_available s
inner join product p on p.product_id = s.product_id
set s.quantity = 0
where p.id_category_default not in (3, 10, 943)
The main problems with your original query are:
the join is missing a predicate on product_id
you wanted AND condition rather than OR; NOT IN comes handy to shorten this.

You can use such an update statement by use of INNER JOIN :
UPDATE stock_available s
JOIN
(
SELECT id
FROM product
WHERE id_category_default NOT IN (3,10,943)
) AS p ON p.id = s.product_id
SET
s.quantity = 0;
where no need a proper query after the keyword JOIN

Related

Select all rows with multiple possible values

I am trying to get all fields from the product table (*) that have the following set of sub_property:
subprop_name=X
subprop_value=Y
I have the following tables :
https://imgur.com/a/y4LGqMI (couldn't upload the picture because the format was not accepted)
So, for an example, if I have two products which has in their sub_property table a entry like this:
subprop_name=X
subprop_value=Y
I would like to return it. As described by the schema, a product can have multiple sub_property entries!
So far, this is what I have:
SELECT prod_id,prod_name from product WHERE product.prod_id IN
(
SELECT property.product_prod_id FROM property WHERE property.prop_id IN
(
SELECT property_prop_id from sub_property WHERE
(
sub_property.subprop_name="Type de scanner" AND sub_property.subprop_value="par transparence"
)
OR
(
sub_property.subprop_name="Pages/minute maximum" AND subprop_value="8.5 pages"
)
)
)
But obviously, it doesn't work because of the 'OR'.
It returns me all items that have one of the set of sub_property instead of all the products that have all the sets of sub_property.
DATABASE HERE
Using JOIN's and an IN for the tupples could be a simple solution for this.
SELECT p.prod_id, p.prod_name
FROM product p
JOIN property AS prop
ON prop.product_prod_id = p.prod_id
JOIN sub_property AS subprop
ON subprop.property_prop_id = prop.prop_id
WHERE (subprop.subprop_name, subprop.subprop_value) IN (
('Type de scanner', 'par transparence'),
('Pages/minute maximum', '8.5 pages')
)
GROUP BY p.prod_id, p.prod_name
So... I am not sure if it's the correct way to validate two answers, but I got 2 working answers.
This is the first one from #Steff Mächtel using LEFT JOIN (https://stackoverflow.com/a/53915792/5454875)
And the second one is from #Shidersz (see comments below the original question), using INNER JOIN)
"I used and approach using INNER JOIN, is something like this what you need? db-fiddle.com/f/t6RrnhDPQuEamjf2bTxFeX/5"
EDIT
#Shidersz solution doesn't work because it selects all products who as at least one of the condition, wich I don't want. I want the product to have all the conditions.
UPDATE 2:
I would suggest to use LEFT JOIN for each property and each sub_property and then check the value inside WHERE condition:
SELECT product.prod_id, product.prod_name
FROM product
LEFT JOIN property AS property_a ON property_a.product_prod_id = product.prod_id AND
property_a.prop_name = "PROPERTY_GROUP_3"
LEFT JOIN sub_property AS sub_property_a ON sub_property_a.property_prop_id = property_a.prop_id AND
sub_property_a.subprop_name="property_4"
LEFT JOIN property AS property_b ON property_b.product_prod_id = product.prod_id AND
property_b.prop_name = "PROPERTY_GROUP_4"
LEFT JOIN sub_property AS sub_property_b ON sub_property_b.property_prop_id = property_b.prop_id AND
sub_property_b.subprop_name="property_3"
WHERE sub_property_a.subprop_value="value_of_property_4" AND
sub_property_b.subprop_value="value_of_property_3"
GROUP BY product.prod_id
Example: https://www.db-fiddle.com/f/wk344Gt6hm98xEhM4jei92/6
Example with 2 new "KEYS" (Index) for better performance:
ALTER TABLE `property`
... ADD KEY `prop_name` (`prop_name`);
ALTER TABLE `sub_property`
... ADD KEY `subprop_name` (`subprop_name`);
https://www.db-fiddle.com/f/wk344Gt6hm98xEhM4jei92/7
Example with INNER JOIN instead of LEFT JOIN
I see no difference with EXPLAIN on test data, maybe Mysql optimizer handles this internal equal
SELECT product.prod_id, product.prod_name
FROM product
INNER JOIN property AS property_a ON property_a.product_prod_id = product.prod_id AND
property_a.prop_name = "PROPERTY_GROUP_3"
INNER JOIN sub_property AS sub_property_a ON sub_property_a.property_prop_id = property_a.prop_id AND
sub_property_a.subprop_name="property_4" AND
sub_property_a.subprop_value="value_of_property_4"
INNER JOIN property AS property_b ON property_b.product_prod_id = product.prod_id AND
property_b.prop_name = "PROPERTY_GROUP_4"
INNER JOIN sub_property AS sub_property_b ON sub_property_b.property_prop_id = property_b.prop_id AND
sub_property_b.subprop_name="property_3" AND
sub_property_b.subprop_value="value_of_property_3"
GROUP BY product.prod_id
https://www.db-fiddle.com/f/wk344Gt6hm98xEhM4jei92/8

optimise Yii2 MYSQL query

I need to optimise my code.it works but takes time and sometimes timeouts.
Objective selected columns from table 1 and table 2 must be combined in another table. duplicates are not allowed in the new table. TIA
$modelsc=Customers::find()->select('customer_id')->all();
$modelsp = Product::find()->select('product_no')->all();
foreach($modelsc as $modelc) {
$user = $connection->createCommand(
'SELECT product_no as product_no,:cust_no as fkcustomer_id
FROM product AS p
WHERE NOT EXISTS( SELECT pc.fkproduct_no
FROM
productcustomer AS pc
WHERE
pc.fkproduct_no = p.Product_no AND fkcustomer_id = :cust_no)');
$user->bindValue(':cust_no', $modelc->customer_id);
$modelsx = $user->queryAll();
Yii::$app->db->createCommand()->batchInsert('productcustomer', [ 'fkproduct_no', 'fkcustomer_id'], $modelsx)->execute(); }
looking to your code you could avoid the not exists clause an try using a left join checkn for null on pc.fkproduct_no
SELECT product_no as product_no,
:cust_no as fkcustomer_id
FROM product AS p
LEFT JOIN productcustomer AS pc ON pc.fkproduct_no = p.Product_no
AND fkcustomer_id = :cust_no
WHERE pc.fkproduct_no is null
Anyway be sure you have proper index on the column where of join condition
for table products an index on column Product_no
for table productcustomer a composite index on (fkcustomer_id, fkproduct_no)

How to update/ make a view updatable in MYSQL

I have created a view via:
CREATE VIEW product_prices
AS SELECT Name, Price
FROM Products;
And I need to update it so prices under £10 are made 10% bigger apart from ones that are in category 3. These need to be looked up in a separate SELECT statement.
I have got this code so far but I'm getting the 1443 error that the definition of the view won't let me update it. How do I make it an updatable view?
UPDATE product_prices
SET Price = Price * 1.1
WHERE Name != (SELECT Name FROM Products WHERE Category_ID = 3)
AND Price < 10;
Use a join instead of <>:
UPDATE product_prices pp LEFT JOIN
Products p
ON p.name = pp.anme and p.Category_ID = 3
SET pp.Price = pp.Price * 1.1
WHERE p.Name IS NULL AND pp.Price < 10;
The issue is the operation on the table being updated, not the view definition.

MySQL - Using column value for joining in the same query

I have three tables that looks something like this:
Table joins
|ID|JOIN_NAME|
1 persons
2 companies
Table information
|ID|JOIN_ID|
1 1
2 2
Table information_extra_persons
|ID|INFORMATION_ID|NAME|
1 1 John
Table information_extra_companies
|ID|INFORMATION_ID|NAME|
1 2 IBM
How can i join together these tables in one SQL? I've tried something like:
SELECT * FROM `information`
INNER JOIN `information_extra_(SELECT `name` FROM `joins` WHERE `id` = `join_id`)`
ON `information_extra_(SELECT `name` FROM `joins` WHERE `id` = `join_id`)`.`information_id` = `information`.`id`
but I can't get it to work. Of course this isn't my actual table setup, but it's the same principle. Does anyone know how to get all the info in just one SQL?
That's actually four tables, not three. This isn't just a nitpick - it looks as though the substance of your question is "how can I use the name of the table as part of the join criteria?" (ie. how can the information_extra_ tables be treated as a single table?)
To which the answer is: you can't. (Outside of dynamic SQL.)
In this specific case, the following should return what I think you are looking for:
select j.join_name joined_entity,
case when j.join_name = 'persons' then p.name
else c.name
end joined_entity_name
from information i
inner join joins j on i.join_id = j.id
left join information_extra_persons p on i.id = p.information_id
left join information_extra_companies c on i.id = c.information_id
Alternatively, a less efficient (but more general) approach might be:
select j.join_name joined_entity,
v.name joined_entity_name
from information i
inner join joins j on i.join_id = j.id
inner join (select 'persons' entity, information_id, name from information_extra_persons
union all
select 'companies' entity, information_id, name from information_extra_companies) v
on i.id = v.information_id and j.join_name = v.entity

Return 2 columns using subquerys in main query in mysql

I wish to populate a table on in a mysql database. Firstly I'd like to pull back all of the possibilities and them trim out the unrequired ones (easier than just adding them by hand).
The final table is:
combinations
combID
productID
type
content
exclude
extrafield2
extrafield6
The data comes from
extrafields_values
exvalueID
productID
extrafieldID
content
For each product I need to get return a row for each combination in extra_field_values (extrafieldID = 2 and extrafieldID = 6)
For instance:
productID = 700
extrafield2 = E, D, F
extrafield6 = 34,35,36,37
Returns the exvalueID to extrafields2 and 6 for each combination
So far I've tried:
SELECT EV.productID, extraFieldID, content AS extrafield6,
(SELECT content AS extrafield2
FROM wjf_extrafields_values AS EV2
INNER JOIN wjf_products AS P2
WHERE extraFieldID = 6) AS extrafield2
FROM wjf_extrafields_values AS EV
INNER JOIN wjf_products AS P ON P.productID = EV.productID
WHERE extrafieldID = 6
I believe you just need to link your wjf_products table to your extrafield_values table twice as shown below.
select p.productID, ev1.content as extrafield2, ev2.content as extrafield6
from wjf_products p inner join extrafields_values ev1 on p.productID = ev1.productID
inner join extrafields_values ev2 on p.productID = ev2.productID
where ev1.extraFieldID = 2
and ev2.extraFieldID = 6
Why not just create and use two views instead of a query.
View1 = Combinations
View2 = Subset of View1
Insert data using the View2