Add Columns for multiple attributes in MySQL - mysql

I'm really not sure how to explain this, since I just started trying to learn how to use MySQL queries in a more advanced way today. Here is what I have:
SELECT pa.displayvalue as Brand
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 113319;
So I have that query, and literally, all I want to do is add another column for the "And an.attributeid = 113319"
I just want to add another column but instead of 113319, I want it to pull the values of let's say 1762 into a column next to it.
So column 1 would have all the values that "And an.attributeid = 113319" pulls, and column two would have all the values that "And an.attributeid = 1762" pulls.
I got this code to work kind of:
SELECT pa.displayvalue as Brand
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 113319;
SELECT pa.displayvalue as Type
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 1762;
But this is returned in navicat as two seperate results. I want both of these to be in one result but as two columns, instead of two results with one column each.
As you can see, all of the lines are the same in each of those Selects except that last line.
I also feel like there is a better way than to have to use that whole code twice just to get another column for an.attributeid. Regardless, I'll take what I can get.
If you have ANY suggestions, I would appreciate it very very much.

If you really want to do that, for formatting or reporting purpose. This is a hack you would use.
And the use of LEFT JOIN would return all rows from the left table, with the matching rows in the right table. The result is NULL in the right side when there is no match.
SELECT p.productid, t2.Type, t1.Brand, t3.Resolution
FROM product p
JOIN
(
SELECT p.productid, pa.displayvalue as Brand
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 113319
) t1 ON t1.productid = p.productid
LEFT OUTER JOIN
(
SELECT p.productid, pa.displayvalue as Type
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 1100
) t2 ON t2.productid = p.productid
LEFT OUTER JOIN
(
SELECT p.productid, pa.displayvalue as Resolution
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 1762
) t3 ON t3.productid = p.productid

You can do something like this
... AND an.attributeid IN (113319, 1762 )
This would return you two rows with one column.
If you want to transpose rows into columns, then that gets a bit more complicated.

This is sometimes called a key-value store. You need to play some games with multiple joins to do what you want.
This sort of thing will do the trick
SELECT whatever,
attr1.displayvalue attr1,
attr2.displayvalue attr2
FROM product p
LEFT JOIN productattribute attr1 ON p.productid = attr1.productid
AND attr1.attributeid = 113319
AND attr1.localeid = 1
AND attr1.isactive = 1
LEFT JOIN productattribute attr2 ON p.productid = attr2.productid
AND attr2.attributeid = 1762
AND attr2.localeid = 1
AND attr2.isactive = 1
You end up joining two copies of the attribute table, and selecting the appropriate attribute id from each in the join condition. You use left join rather than ordinary join so you still get the row even if the attribute is missing.
A very common example in the wild of this data organization is the wp_postmeta table in WordPress.

Related

SQL query to create new meta descriptions in spreadsheet

I building a custom SQL query of a product name with id_product, id_lang, id_manufacturer, category, meta_description, brand name and multiple feature ids. This SQL query shows no result.
Here's my query:
SELECT pl.id_product, pl.id_lang, ml.id_manufacturer, p.active, pl.name as name_product, fp.id_feature as name_attribute, cl.name as category, m.name as brand, pl.meta_description
FROM pr_product p
LEFT JOIN pr_product_lang pl ON (p.id_product = pl.id_product)
LEFT JOIN pr_category_lang cl ON (cl.id_category = p.id_category_default and cl.id_lang = pl.id_lang)
LEFT JOIN pr_lang l on (l.id_lang = pl.id_lang)
LEFT JOIN pr_manufacturer_lang ml on (l.id_lang = pl.id_lang and l.id_lang = ml.id_lang)
LEFT JOIN pr_manufacturer m on (ml.id_manufacturer = m.id_manufacturer)
LEFT JOIN pr_feature_product fp on (pl.id_product = fp.id_product)
Where l.active = 1 AND pl.id_lang = 2 AND cl.name = 9 and fp.id_feature = 2 AND fp.id_feature = 3 AND fp.id_feature = 35 AND fp.id_feature = 39
Order by p.id_product, pl.id_lang, ml.id_manufacturer, fp.id_feature
The goal is to creat a new meta description in the spreadsheet and import it to the database. In php, the query would be easier, but I have zero knowledge about it.

MySQL query with multiple INNER JOIN returns duplicate entries in the result

I have the following data structure:
There are multiple tables:
I need the following return: sum of balance (sum(a.balance) as pnl) from tabposition.
However, this query returns duplicate results. Can anybody help me with this? Thanks
SET #dt_inicio := '2021-12-01';
SET #dt_fim := '2021-12-09';
select a.data, a.fund, 'CASH-USD' as ticker , 'CASH' as strategy, 'Dolar Cash' as company,
'Others' as type, 'Others' as sector,
sum(a.balance) as pnl from tabposition as a
inner join tablistaativos as c on a.ticker = c.ticker
inner join tabdiautil as d on a.data = d.data_util
inner join tabhistorynav as e on a.data = e.data
inner join tabhistorynav as f on d.data_util_ant = f.data
inner join tabprice as g on a.data = g.data
inner join tabprice as i on d.data_util_ant = i.data
inner join tabhistorynav as j on d.data_util_ant = j.data and a.fund = j.fund
inner join tabfatorx as l on a.data = l.data_pos
where a.data >= #dt_inicio and a.data <= #dt_fim and a.fund = 'TORK FUND' and a.qnt <> 0
and (c.class = 'ACCO' or c.class = 'ACCOUNTING' or c.class = 'SPAC' or c.class = 'ACOES' or
c.class = 'OPCOES' or c.class = 'FUNDO')
and e.official = 'Yes' and e.fund = 'TORK FIA' and f.official = 'Yes' and f.fund = 'TORK FIA'
and g.ticker = 'usdbrl' and i.ticker = 'usdbrl'
and l.cotista = 'TORK FIA'
group by a.data
order by a.data

SQL orderby select

i have SQL query. I would like to orderby this by parent category. But i return only default category. I would like to know if i can
ORDER BY SELECT id_parent FROM cats WHERE id_category = id_default_category
Here is my query :
SELECT cp.`id_product_attribute`,
cp.`id_product`, cp.`quantity` AS cart_quantity,
cp.id_shop, pl.`name`,
p.`is_virtual`,
pl.`description_short`,
pl.`available_now`,
pl.`available_later`,
product_shop.`id_category_default`,
p.`id_supplier`,
p.`id_manufacturer`,
product_shop.`on_sale`,
product_shop.`ecotax`,
product_shop.`additional_shipping_cost`,
product_shop.`available_for_order`,
product_shop.`price`,
product_shop.`active`,
product_shop.`unity`,
product_shop.`unit_price_ratio`,
stock.`quantity` AS quantity_available,
p.`width`,
p.`height`,
p.`depth`,
stock.`out_of_stock`,
p.`weight`,
p.`date_add`,
p.`date_upd`,
IFNULL(stock.quantity, 0) as quantity,
pl.`link_rewrite`,
cl.`link_rewrite` AS category,
CONCAT(LPAD(cp.`id_product`, 10, 0),
LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0),
IFNULL(cp.`id_address_delivery`, 0)) AS unique_id,
cp.id_address_delivery,
product_shop.advanced_stock_management,
ps.product_supplier_reference supplier_reference
FROM `ps_cart_product` cp
LEFT JOIN `ps_product` `p` ON p.`id_product` = cp.`id_product`
INNER JOIN `ps_product_shop` product_shop ON (product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)
LEFT JOIN `ps_product_lang` `pl` ON p.`id_product` = pl.`id_product`
AND pl.`id_lang` = 1 AND pl.id_shop = cp.id_shop
LEFT JOIN `ps_category_lang` `cl` ON product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = 1 AND cl.id_shop = cp.id_shop
LEFT JOIN `ps_product_supplier` `ps` ON ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`
LEFT JOIN ps_sanishopstock_available stock
ON (stock.id_product = cp.id_product AND stock.id_product_attribute = IFNULL(`cp`.id_product_attribute, 0) AND stock.id_shop = 1 AND stock.id_shop_group = 0 )
WHERE cp.`id_cart` = 757
ORDER BY product_shop.id_category_default ASC, cp.id_product, cp.date_add ASC;
There is a lot of different table, i'm lost !
If someone have any idea.
Thanks a lot !
Yes. But like any subquery, you need parentheses:
ORDER BY (SELECT c.id_parent FROM cats c WHERE id_category = id_default_category)
I would also qualify the column names in the WHERE, but I don't know where they come from.

mysql joins to return perfect result

I have bought two courses VLSI electronics and VLSI extc which were
bought together so it has same order id
The query returns result when we searched for vlsi or electronics but
doesn't result anything when search in the filterextc.
SELECT `i.*,r.emailid,r.first_name,u.university_name,ct.country_name,st.state_name, cy.city_name,r.address,r.mobile,COUNT( k.order_id ) as order_cnt, k.product_type AS product_type,k.product_id AS product_id,tx.tax_amount,str.stream_name,fie.field_name,sems.semester_number,colg.college_name,`
IF( product_type = "course", (SELECT course_title FROM tbl_courses WHERE course_id = product_id AND course_title Like "%vlsi%"), 0 ) AS coursebought,
IF(product_type = "module",(SELECT module_title FROM tbl_modules WHERE module_id = product_id ), 0 ) AS modulebought
FROM (`tbl_orders` AS i)
LEFT JOIN tbl_users AS r ON i.user_id = r.user_id
LEFT JOIN tbl_discount_history AS hd ON i.order_id = hd.order_id
AND i.discount_id = hd.discount_id
AND hd.status = "Active"
LEFT JOIN tbl_shopping_cart AS k ON i.order_id = k.order_id
LEFT JOIN tbl_university AS u ON u.university_id = r.university_id
LEFT JOIN tbl_country AS ct ON u.country_id = ct.country_id
LEFT JOIN tbl_states AS st ON u.state_id = st.state_id
LEFT JOIN tbl_city AS cy ON u.city_id = cy.city_id
LEFT JOIN tbl_finalorder_tax_details AS tx ON i.order_id = tx.order_id
LEFT JOIN tbl_stream AS str ON r.stream_id = str.stream_id
LEFT JOIN tbl_fields AS fie ON r.field_id = fie.field_id
LEFT JOIN tbl_semester_type AS sems ON r.semester_id = sems.semester_id
LEFT JOIN tbl_colleges AS colg ON r.college_id = colg.college_id
and ct.country_id = cy.city_country_id
and st.state_id = cy.city_state_id
WHERE tx.tax_id = 1 and r.status = "Active" And 1=1 AND product_id IS NOT NULL
AND product_type = "course"
GROUP BY order_id
having coursebought IS NOT NULL and modulebought IS NOT NULL
ORDER BY order_id desc
limit 0,10

Mysql update using select

I'm trying to update the fields by using below query. What is the error in below query ?
MySQL said: Documentation
1064 - 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 'FROM orders cl' at line 2
update hedging SET
Dept = concat(RIGHT( dpt.DeptName,2),LEFT( grp.GroupName,3),LEFT( st.Login,3)),
OrderNo = cl.OrderNo,Client = cn.ShortName,
Currency = cur.Notation, SellingAmount = pto.PIAmount ,
BuyingAmount = pto.POAmount
FROM orders cl
left join client cn on cl.ClientID = cn.ClientID
inner join department dpt on cl.DeptID = dpt.DeptID
inner join supplier sp on cl.SupplierID = sp.SupplierId
left join staff st on st.StaffID = cl.SalesPerson
left join pipo_total pto on pto.OrderNo = cl.OrderNo
inner join groups grp on cl.GroupID = grp.GroupID
left join currency cur on cur.CurrencyID= cl.SellCurrencyID
left join hedging hed on hed.OrderNo = cl.OrderNo)
where cur.Notation <> 'USD' and cl.OrderType = '1' and hed.OrderNo = cl.OrderNo
Try 1
update orders cl
left join client cn on cl.ClientID = cn.ClientID
inner join department dpt on cl.DeptID = dpt.DeptID
inner join supplier sp on cl.SupplierID = sp.SupplierId
left join staff st on st.StaffID = cl.SalesPerson
left join pipo_total pto on pto.OrderNo = cl.OrderNo
inner join groups grp on cl.GroupID = grp.GroupID
left join currency cur on cur.CurrencyID= cl.SellCurrencyID
left join hedging hed on hed.OrderNo = cl.OrderNo
SET hed.Dept = concat(RIGHT( dpt.DeptName,2),LEFT( grp.GroupName,3),LEFT( st.Login,3))
,hed.OrderNo = cl.OrderNo
,hed.Client = cn.ShortName
,hed.Currency = cur.Notation
,hed.SellingAmount = pto.PIAmount
,hed.BuyingAmount = pto.POAmount
where cur.Notation <> 'USD' and cl.OrderType = '1' and hed.OrderNo = cl.OrderNo
UPDATE with multiple tables should be something like this
UPDATE table1 t1
INNER JOIN table2 t2 ON t1.ID = t2.ID
SET t1.value = [value]
Edit: Your updated query
update orders cl
left join client cn on cl.ClientID = cn.ClientID
inner join department dpt on cl.DeptID = dpt.DeptID
inner join supplier sp on cl.SupplierID = sp.SupplierId
left join staff st on st.StaffID = cl.SalesPerson
left join pipo_total pto on pto.OrderNo = cl.OrderNo
inner join groups grp on cl.GroupID = grp.GroupID
left join currency cur on cur.CurrencyID= cl.SellCurrencyID
left join hedging hed on hed.OrderNo = cl.OrderNo)
SET Dept = concat(RIGHT( dpt.DeptName,2),LEFT( grp.GroupName,3),LEFT( st.Login,3))
,OrderNo = cl.OrderNo
,Client = cn.ShortName
,Currency = cur.Notation
,SellingAmount = pto.PIAmount
,BuyingAmount = pto.POAmount
where cur.Notation <> 'USD' and cl.OrderType = '1' and hed.OrderNo = cl.OrderNo