SELECT p.id
FROM produkty p, przyporzadkowania pr, stany_magazynowe, gk_grupy_produkty
INNER JOIN sub_subkategorie ssi
ON pr.sub_subkategorie_id = ssi.ID
Tables and their important fields
produkty - id, pozycja
przyporzadkowania - id, produkt_id, sub_kategoria_id, sub_subkategoria_id
sub_subkategorie - id, subkategorie_id, pozycja
subkategorie - id, kategorie_id, pozycja
kategorie - id, pozycja
Error "#1054 - Unknown column 'pr.sub_subkategorie_id' in 'on clause'"
Tried with
SELECT p.id, pr.sub_subkategorie_id
Same result.
Full query (not tested due to failure of query above):
SELECT p.id
FROM produkty p, przyporzadkowania pr, stany_magazynowe, gk_grupy_produkty
INNER JOIN sub_subkategorie ssi ON pr.sub_subkategorie_id = ssi.ID
INNER JOIN subkategorie si ON ssi.subkategorie_id = si.id
INNER JOIN kategorie c ON si.kategorie_id = c.id
WHERE stany_magazynowe.produkty_id = p.id
AND p.id = pr.produkty_id
AND pr.sub_subkategorie_id =1
AND p.widoczny = '1'
AND p.id = gk_grupy_produkty.id_produktu
AND gk_grupy_produkty.id_grupy =1
AND gk_grupy_produkty.towar_widocznosc =1
AND c.id = '1'
ORDER BY c.pozycja, si.pozycja, ssi.pozycja, p.pozycja
Hope that I gave enough info (earlier question - SELECT * FROM table WHERE field IN (SELECT id FROM table ORDER BY field2))
EDIT:
Yes, there is typo, but only here, on stackoverflow (too much coffee, my fingers are flying). Thank you all, You saved my day!
You're joining the tables in the wrong order:
SELECT p.id
FROM produkty p, stany_magazynowe, gk_grupy_produkty, przyporzadkowania pr
INNER JOIN sub_subkategorie ssi
ON pr.sub_subkategorie_id = ssi.ID
The error is due to the higher precedence of the JOIN keyword compared to the comma. Errors like this are one of the reasons why I would urge you not to use the implicit join syntax with the comma and instead always write your joins explicitly using the JOIN keyword.
Here is your complete query rewritten using explicit joins:
SELECT p.id
FROM produkty p
INNER JOIN przyporzadkowania pr ON p.id = pr.produkty_id
INNER JOIN stany_magazynowe ON stany_magazynowe.produkty_id = p.id
INNER JOIN gk_grupy_produkty ON p.id = gk_grupy_produkty.id_produktu
INNER JOIN sub_subkategorie ssi ON pr.sub_subkategorie_id = ssi.ID
INNER JOIN subkategorie si ON ssi.subkategorie_id = si.id
INNER JOIN kategorie c ON si.kategorie_id = c.id
WHERE pr.sub_subkategorie_id = 1
AND p.widoczny = '1'
AND gk_grupy_produkty.id_grupy =1
AND gk_grupy_produkty.towar_widocznosc =1
AND c.id = '1'
ORDER BY c.pozycja, si.pozycja, ssi.pozycja, p.pozycja
Related question
Mixing implicit and explicit JOINs
You are mixing "classical" joins with the join keyword. You should use the join keyword for all the joins.
The error comes from that you are joining on the gk_grupy_produkty table, where that field doesn't exist. The database really looks at your query as:
SELECT p.id
FROM
produkty p,
przyporzadkowania pr,
stany_magazynowe,
(gk_grupy_produkty INNER JOIN sub_subkategorie ssi ON pr.sub_subkategorie_id = ssi.ID)
You should use:
SELECT p.id
FROM
produkty p
INNER JOIN przyporzadkowania pr ON p.id = pr.produkty_id
INNER JOIN stany_magazynowe ON stany_magazynowe.produkty_id = p.id
INNER JOIN gk_grupy_produkty ON p.id = gk_grupy_produkty.id_produktu
INNER JOIN sub_subkategorie ssi ON pr.sub_subkategorie_id = ssi.ID
INNER JOIN subkategorie si ON ssi.subkategorie_id = si.id
INNER JOIN kategorie c ON si.kategorie_id = c.id
WHERE
pr.sub_subkategorie_id = 1 AND
p.widoczny = '1' AND
gk_grupy_produkty.id_grupy = 1 AND
gk_grupy_produkty.towar_widocznosc = 1 AND
c.id = '1'
ORDER BY c.pozycja, si.pozycja, ssi.pozycja, p.pozycja
Is the column named sub_subkategoria_id a typo?
Start with this: (fill in the ???)
SELECT p.id
FROM produkty p
JOIN przyporzadkowania pr ON p.??? = pr.???
JOIN sub_subkategorie ssi ON pr.sub_subkategorie_id = ssi.ID
(You don't need to specify INNER)
Your original FROM clause:
FROM produkty p, przyporzadkowania pr, stany_magazynowe, gk_grupy_produkty
Has tables p and pr for which no JOIN condition is specified which will result in a cartesian product or cross join (probably not a good thing in this case) as well as tables that aren't referenced anywhere else in your query:
stany_magazynowe, gk_grupy_produkty
Specify a JOIN for
produkty p AND przyporzadkowania pr
and remove
stany_magazynowe, gk_grupy_produkty
Hint: If you do not reference any columns from a table in your SELECT, ORDER BY, GROUP BY, WHERE then the table probably does not belong in your FROM clause. (Unless it's a join/junction table.)
Related
I'm using mysql 8.0.31 version.
Below is my database schema ERD.
I want to get inforamtion about products from my DB.
Below is my sql raw query.
SELECT
p.id, p.name, sc.name sub_category, c.name category, count(po.color_id) color_count
FROM products p
INNER JOIN sub_categories sc
ON sc.id = p.sub_category_id
INNER JOIN categories c
ON sc.category_id = c.id
LEFT JOIN products_options po
ON po.product_id = p.id
INNER JOIN genders g
ON po.gender_id = g.id
WHERE c.id = 1
GROUP BY p.id
ORDER BY p.id ASC;
I want to join products table with sub_categories, categories to get categories information about my products AND products table with products_options, colors, genders to get color_count about a product and gender type about a product.
So I wanted to query like this added g.type (gender type information for a product)
SELECT
p.id, p.name, sc.name sub_category, c.name category, count(po.color_id) color_count, g.type
FROM products p
INNER JOIN sub_categories sc
ON sc.id = p.sub_category_id
INNER JOIN categories c
ON sc.category_id = c.id
LEFT JOIN products_options po
ON po.product_id = p.id
INNER JOIN genders g
ON po.gender_id = g.id
WHERE c.id = 1
GROUP BY p.id
ORDER BY p.id ASC;
But this occurs error like this
SQL Error [1055] [42000]: Expression #6 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.g.type' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
I think this error occurs cuz I didn't use aggregate function for g.type.
Below is my result except g.type in sql select field.
I want to get genders.type field together.
I think I need to sub query and join that table created by sub query. But I don' t know well How can I implement that method.
To combine this gender type information, How can I modify my sql query?
I tried multiple method sql queries in various ways to join table.
You need to either remove the column from select list like:
SELECT p.id, count(po.color_id) color_count
FROM products p
INNER JOIN sub_categories sc
ON sc.id = p.sub_category_i`enter code here`d
INNER JOIN categories c
ON sc.category_id = c.id
LEFT JOIN products_options po
ON po.product_id = p.id
INNER JOIN genders g
ON po.gender_id = g.id
WHERE c.id = 1
GROUP BY p.id
ORDER BY p.id ASC;
or add in group by clause the select columns like:
SELECT p.id, p.name, sc.name sub_category, c.name category, count(po.color_id) color_count, g.type
FROM products p
INNER JOIN sub_categories sc
ON sc.id = p.sub_category_id
INNER JOIN categories c
ON sc.category_id = c.id
LEFT JOIN products_options po
ON po.product_id = p.id
INNER JOIN genders g
ON po.gender_id = g.id
WHERE c.id = 1
GROUP BY p.id,p.name, sc.name sub_category, c.name category, g.type
ORDER BY p.id ASC;
I have an SELECT statement that has a huge number of left join and I want to filter some out.
When I check how many records i have in total and subtract the records with my LIKE statements, I should get the amount that is not affected by my restrictions.
But when I negate my restriction to get the ones I didn't affect, I get an different number than calculated.
SQL without restrictions (Record count: 13.251.981)
SELECT p.product_number
FROM product p
LEFT JOIN product_category pc on p.id = pc.product_id
LEFT JOIN product_category_tree pct on p.id = pct.product_id
LEFT JOIN product_configurator_setting pcs on p.id = pcs.product_id
LEFT JOIN product_cross_selling pcs2 on p.id = pcs2.product_id
LEFT JOIN product_cross_selling_assigned_products pcsap on p.id = pcsap.product_id
LEFT JOIN product_cross_selling_translation pcst on pcs2.id = pcst.product_cross_selling_id
LEFT JOIN product_custom_field_set pcfs on p.id = pcfs.product_id
LEFT JOIN product_media pm on p.id = pm.product_id
LEFT JOIN product_option po on p.id = po.product_id
LEFT JOIN product_price pp on p.id = pp.product_id
LEFT JOIN product_property pp2 on p.id = pp2.product_id
LEFT JOIN product_review pr on p.id = pr.product_id
LEFT JOIN product_search_keyword psk on p.id = psk.product_id
LEFT JOIN product_tag pt on p.id = pt.product_id
LEFT JOIN product_translation pt2 on p.id = pt2.product_id
LEFT JOIN product_visibility pv on p.id = pv.product_id
With restriction (Record count: 9.285.545)
WHERE p.product_number NOT LIKE 'SW%'
AND p.product_number NOT LIKE '%.%'
AND pt2.name NOT LIKE '%Gutschein'
AND pt2.name NOT LIKE '%Test%'
With negated restriction (Record count: 100.851)
WHERE p.product_number LIKE 'SW%'
OR p.product_number LIKE '%.%'
OR pt2.name LIKE '%Gutschein'
OR pt2.name LIKE '%Test%';
From my calculations i should get 3.966.436 records that don't get affected. (13.251.981 - 9.285.545 = 3.966.436)
But instead I get 100.851
How is that possible?
The solution for me was actually this WHERE:
WHERE p.product_number < 'SW'
I have this query and I am getting error #1066 - Not unique table/alias: 'components'. What seems to be the issue?
SELECT COUNT(*) FROM `products`, `components`, `tradeNames`
INNER JOIN `componentsMap` ON componentsMap.product_id = product.id
INNER JOIN `components` ON componentsMap.component_id = components.id
INNER JOIN `tradeNamesMap` ON .tradeNamesMap.product_id = products.id
INNER JOIN `tradeNames` ON tradeNamesMap.tradeName_id = tradeNames.id
WHERE (((((LOWER(inci) LIKE '%abies%')
OR (trade_name.LOWER(name) LIKE '%abies%'))
OR (components.LOWER(no_cas)='abies'))
OR (components.LOWER(no_einecs)='abies'))
OR (components.LOWER(name)='abies'))
AND (`published`=1)
ORDER BY `trade_name`.`name` DESC
You don't need to list the tables before the INNER JOINs. In fact, simply don't ever use commas in the FROM clause. So:
SELECT COUNT(*)
FROM `products`
INNER JOIN `componentsMap` ON componentsMap.product_id = product.id
INNER JOIN `components` ON componentsMap.component_id = components.id
INNER JOIN `tradeNamesMap` ON tradeNamesMap.product_id = products.id
INNER JOIN `tradeNames` ON tradeNamesMap.tradeName_id = tradeNames.id
WHERE (((((LOWER(inci) LIKE '%abies%')
OR (trade_name.LOWER(name) LIKE '%abies%'))
OR (components.LOWER(no_cas)='abies'))
OR (components.LOWER(no_einecs)='abies'))
OR (components.LOWER(name)='abies'))
AND (`published`=1)
ORDER BY `trade_name`.`name` DESC;
The above query only returns one row because of the COUNT(). The order by suggests that you actually want this information for each trade_name.name. If so, you need a GROUP BY:
SELECT tn.name, COUNT(*)
FROM `products` p INNER JOIN
`componentsMap cm
ON cm.product_id = p.id INNER JOIN
`components` c
ON cm.component_id = c.id INNER JOIN
`tradeNamesMap` tnm
ON tnm.product_id = p.id INNER JOIN
`tradeNames` tn
ON tnm.tradeName_id = tn.id
WHERE ((LOWER(inci) LIKE '%abies%') OR
(tn.LOWER(name) LIKE '%abies%') OR
(c.LOWER(no_cas)='abies') OR
(c.LOWER(no_einecs)='abies') OR
(c.LOWER(name)='abies')
) AND
(`published` = 1)
GROUP BY tn.name
ORDER BY tn.`name` DESC
INNER JOIN `[components]` ON componentsMap.component_id = components.id
AND
SELECT COUNT(*) FROM `products`, [`components`], `tradeNames`
Two components are there.
Just guessing, and untested, but I suspect that something like this would do what you're after...
SELECT n.name
, COUNT(*)
FROM products p
JOIN componentsMap pc
ON pc.product_id = p.id
JOIN components c
ON c.id = pc.component_id
JOIN tradeNamesMap pn
ON pn.product_id = p.id
JOIN tradeNames n
ON n.id = pn.tradeName_id
WHERE
( inci LIKE '%abies%'
OR n.name LIKE '%abies%'
OR 'abies' IN (c.no_cas,c.no_einecs,c.name)
)
AND published = 1
GROUP
BY n.name
ORDER
BY n.name DESC
I have following query.
select
Product.*,
(
select
group_concat(features.feature_image order by product_features.feature_order)
from product_features
inner join features
on features.id = product_features.feature_id
where
product_features.product_id = Product.id
and product_features.feature_id in(1)
) feature_image
from products as Product
where
Product.main_product_id=1
and Product.product_category_id='1'
I want to bypass the row if feature_image is empty.
Your query looks a bit strange because you are doing most of the work in a subquery:
select p.*, (select group_concat(f.feature_image order by pf.feature_order)
from product_features pf inner join
features f
on f.id = pf.feature_id
where pf.product_id = p.id and pf.feature_id in (1)
) as feature_image
from products p
where p.main_product_id=1 and p.product_category_id='1';
A more common way to phrase the query is as an inner join in the outer query:
select p.*, group_concat(f.feature_image order by pf.feature_order) as feature_image
from products p join
product_features pf
on pf.product_id = p.id and pf.feature_id in (1) join
features f
on f.id = pf.feature_id
where p.main_product_id=1 and p.product_category_id='1'
group by p.id;
This will automatically include only products that have matching features. You would use left outer join to get all products.
I'm trying to do the following MySql query and when i go to run it, it tells me that "q.object_id" in the sub-query is unknown (if i change it to o.id, it says the same).
SELECT q.*, (SELECT c.title
FROM api_course c
LEFT OUTER JOIN api_object_parents op
ON c.object_id = op.parent
AND op.object_id = q.object_id) as parent_title
FROM api_quiz q
LEFT OUTER JOIN api_object o ON q.object_id = o.id
WHERE o.type = 'Quiz'
Basically i need to get the same id that is being used in the main query and use that in a sub-query.
Thanks!
is this what you are looking for?
SELECT a.*, d.title
FROM api_quiz a
LEFT JOIN api_object b
on a.object_id = b.id
LEFT JOIN api_object_parents c
ON c.parent = a.object_id
LEFT JOIN api_course d
ON c.object_id = c.parent