How to select multiple fields in MySQL query when using INNER JOIN - mysql

I want to select multiple fields from table p.
The second line of this code is wrong. how to write?
except p.*
I don't want p.*
SELECT
p.id, title, price
c.`title` as `CategoryTitle`
from `tbl_products` p
INNER JOIN `tbl_categories` c
ON p.`category_FK` = c.`id`

Well, you might have your own reason so, perhaps you can do something like this:
SELECT
id, title, price, CategoryTitle
FROM `tbl_products` p
INNER JOIN
(SELECT `title` AS 'CategoryTitle', id AS 'CategoryID'
FROM `tbl_categories`) c
ON category_FK = CategoryID
Make one of the table as a subquery and define column alias that's not a duplicate with the other table. In your example, it seems like both of your tables have columns with similar names like id & title. Once you define those similar column names in the subquery with different alias, then you won't need to do p.xx or c.xx.

Related

How to update multiple rows on table with the result of a select subquery in Mysql

I have a table "product_quantity_cart" that has a "price" column in Mysql. I want to update all rows that match certain "id" with the result of a select that uses values from two different tables. In order to do so, I am executing a select subquery inside the update and as a result I am getting error 1224: "subquery returns multiple rows". I have read that a subquery like mine is not the right way to achieve what I want in Mysql, so I would like to ask which is the proper way to do it.
My query looks like so:
update product_quantity_cart set price_product =
(
select quantity*price from (select * from product_quantity_cart) as p_q_c inner join product
on product.id_product=p_q_c.id_product
where id_shopping_cart=7
);
'''
As you can see, I intend to update column price_product in all rows from table product_quantity_cart.
I don't know what your tables looks like but I'm just assuming that the product in your inner join product (given above) is your table2 with columns p.id_product and p.quantity and your product_quantity_cart has columns id_product, price_product, c.price, and c.id_shopping_cart
Then the query could be like this;
update product_quantity_cart c JOIN product p ON p.id_product = c.id_product
set c.price_product = c.price * p.quantity
WHERE c.id_shopping_cart=7

SQL query with JOIN

I'm creating a product filter for e-commerce store. I have a product table, characteristics table and a table in which I store product_id, characteristic_id and a single filter value.
shop_products - id, name
shop_characteristics - id, values (json)
shop_values - product_id, characteristic_id, value
I can build a query to get all the products by a single value like this:
SELECT `p`.* FROM `shop_products` `p`
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id`
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
It works fine. Also, I can modify this query and get all the products by multiple values that belong to the very same characteristics group (have identical characteristics_id) like this:
SELECT `p`.* FROM `shop_products` `p`
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id`
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
OR ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='indoor'))
but when I try to create a query for multiple conditions with different characteristic_id I get nothing
SELECT `p`.* FROM `shop_products` `p`
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id`
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
AND ((`fv`.`characteristic_id`=5) AND (`fv`.`value`='white'))
My guess it does not work because of AND operator that I am using wrong in this case due to there are no records in shop_values table that have both characteristic_id 3 and 5.
So my question is how to combine or modify my query to get all related products or maybe it is a flaw to store data like this and I need to create a different kind of shop_values table?
Use aggregation. You can also use tuples with the in clause. So:
SELECT p.*
FROM shop_products p JOIN
shop_values v
ON p.id = v.product_id
WHERE (v.characteristic_id, v.value) IN ( (3, 'outdoor'), (5, 'white'))
GROUP BY p.id
HAVING COUNT(DISTINCT v.characteristic_id) = 2;
Notes:
Unnecessarily escaping column and table aliases (with backticks) just makes the query harder to write and to read.
In general, using SELECT p.* and GROUP BY p.id is really, really bad form. The one exception is when you are grouping by a unique or primary key. This latter form is actually supported in the ANSI standard.
A LEFT JOIN is not needed. You need to find matches between the tables for the logic to work.
The use of AND and OR is fine for the WHERE clause. MySQL happens to support tuples with IN, which somewhat simplifies the logic.

How to show name of position from second table based on number of rows in first table?

I have two tables "Employees" and "Positions"
I want to write a query that show the name of the Position that appears least in table "Employees" I have foreign key "ID_of_Position" in "Employees".
I came up with something like this, but it might not work:
SELECT Employees.ID_of_Position, Positions.ID_of_Position, Positions.Name_of_Position
FROM Positions
WHERE Employees.ID_of_Position in (SELECT ID_of_Position
FROM Employees
GROUP BY ID_of_Position
HAVING COUNT(ID_of_Position
)=1)
INNER JOIN Employees ON Positions.ID_of_Position = Employees.ID_of_Position;
The proper syntax would look like:
SELECT e.ID_of_Position, p.ID_of_Position, p.Name_of_Position
FROM Positions p JOIN
Employees e
ON p.ID_of_Position = e.ID_of_Position
WHERE e.ID_of_Position in (SELECT ID_of_Position
FROM Employees
GROUP BY ID_of_Position
HAVING COUNT(ID_of_Position) = 1
);
This doesn't answer the question (unless there is a position with exactly one employee), but it is at least syntactically correct.
It is important to understand that SELECT, FROM, and WHERE are all clauses in the SELECT statement. JOIN is an operator in the FROM clause.
At least where should be after join, and there is something with parentheses at the end ...
SELECT Employees.ID_of_Position, Positions.ID_of_Position, Positions.Name_of_Position
FROM Positions
INNER JOIN Employees ON Positions.ID_of_Position = Employees.ID_of_Position;
WHERE Employees.ID_of_Position in (SELECT ID_of_Position
FROM Employees
GROUP BY ID_of_Position
HAVING COUNT(ID_of_Position)=1
)

How to create view in query having JOINS?

Hello I am not able to create view for following query.
create view my_View as
select * from product p
LEFT JOIN product_description pd ON (p.product_id=pd.product_id)
I have two tables
TABLE1 :-
Product with column as :- product_id, column2,column3
TABLE2 :- Product_Description with column as:- product_id , column4,column5.
Here product_id is foreign key for Product table.
Following is the error I am getting
Error Code: 1060. Duplicate column name 'product_id'
I am using mysql workbench to run my queries. Looking at the error, I understand that I need to assign alias. But I am required to join more than 5-8 tables thats the reason I am looking for better solution.
The Error is coming due to same column name in both the tables, second thing is its never a good practice to fetch all records in views by using * until and unless you really want all records from all table that you are using in join condition.
What you can do is select records specific to your view, like
select p.*,pd.somefield from product p
LEFT JOIN product_description pd ON (p.product_id=pd.product_id)
In the above query your product_id is fetched from product table only and you can fetch only necessary fields from product_description table
The easiest solution in your case is to use using instead of on:
create view my_View as
select *
from product p LEFT JOIN
product_description pd
USING (product_id);
In general, though, you should list the columns explicitly in the select rather than using *.
SELECT * will select all columns from both tables in the join. But both tables have a column called product_id, so you'll get two columns in the view with the same name.
You need to list out all the columns, so you can give an alias to product_description.product_id to distinguish it:
SELECT p.product_id, p.column2, p.column3, pd.product_id AS pd_id, pd.column4, pd.column5
FROM product AS p
LEFT JOIN product_description AS pd ON p.product_id = pd.product_id

mysql match letter/number field with letter field without duplicates

i have fields in two mysql tables i need to match... in the product table i have mixed letter/number keys (product_code) such as MM123 and then in a collection table i have just the letters as a key (collection_code) such as MM...
i tried this:
select p.*
from product p, collection c
where p.product_code LIKE CONCAT(c.collection_code ,'%')
however i'm getting multiple entries matched because collection_code has entries such both M and MM so it returns for both product_code = M123 and product_code = MM123
i think what i want is something like this:
select p.*
from product p, collection c
where p.product_code LIKE CONCAT(c.collection_code ,REGEXP '[^0-9 \.]+')
but i cant seem to get it exactly
SELECT p.*
FROM product p
JOIN collection c
ON p.product_code REGEXP CONCAT('^', c.collection_code, '[0-9]+$')