Have three tables that look like this:
PersonTable
Person.ID
Person.Name
PersonTypeCompositeTable
Person.ID
PersonType.ID
PersonTypeTable
PersonType.ID
PersonType.Category
For this example, say the values of PersonTypeCompositeTable are:
1,A
2,A
3,B
How to I write a SELECT statement that will return all the people with a PersonType of "A"?
UPDATE: (Working version of answer posted)
SELECT p.*
FROM PersonTable p
INNER JOIN PersonTypeCompositeTable ptc
ON p.ID = ptc.ID
INNER JOIN PersonTypeTable pt
ON ptc.ID = pt.ID
WHERE pt.Category = 'A'
You use joins between the three tables.
SELECT p.*
FROM PersonTable p
INNER JOIN PersonTypeCompositeTable ptc
ON p.Person.ID = ptc.Person.ID
INNER JOIN PersonTypeTable pt
ON ptc.PersonType.ID = pt.PersonType.ID
WHERE pt.PersonType.Category = 'A'
Related
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 have three tables
profiles (id, name, deleted)
categories (id, name, deleted)
profiles_categories (id, profile_id, category_id, , deleted)
How i can select all profiles with name in categories?
I trying something like this, but its not works...
SELECT *
FROM profiles p
JOIN categories c, profiles_categories pc
WHERE p.id = pc.profile_id
AND WHERE pc.id = c.category_id
Thanks
EDIT
SELECT *
FROM profiles p
INNER JOIN profiles_categories pc
ON p.id = pc.profile_id
INNER JOIN categories c
ON pc.id = c.id
its return only for one profile (now only two active profiles, but only first have categories)
You have several issues with your current query.
First, you are mixing join types. You should use ANSI JOIN syntax between all of the tables. Don't mix ANSI JOIN syntax with some tables and then commas between other tables.
Second, you have two WHERE clauses and you can only have one WHERE clause.
Finally, you should include the column names that you want to return instead of SELECT *
The query should be similar to this:
SELECT p.name, c.name
FROM profiles p
INNER JOIN profiles_categories pc
ON p.id = pc.profile_id
INNER JOIN categories c
ON pc.id = c.category_id
An INNER JOIN between the tables will return all rows that exist in all of the tables.
Note, based on your table structure you might be able to use the following which returns the profiles that have a corresponding row in the the profiles_categories table:
select p.name
from profiles p
where p.id in (select profile_id
from profiles_categories);
Edit you want to return all profiles regardless of whether or not then have a category, then you need to use a LEFT JOIN:
SELECT p.name, c.name
FROM profiles p
LEFT JOIN profiles_categories pc
ON p.id = pc.profile_id
LEFT JOIN categories c
ON pc.id = c.category_id
SELECT *
FROM profiles p
JOIN profiles_categories pc on p.id = pc.profile_id
JOIN categories c on pc.id = c.category_id
or
SELECT *
FROM profiles p, categories c, profiles_categories pc
WHERE p.id = pc.profile_id
AND pc.id = c.category_id
try this:
SELECT *
FROM profiles p
JOIN profiles_categories pr on p.id = pr.profile_id
JOIN categories c on pr.id = c.category_id
WHERE c.name='thename'
I have a problem with a query:
I have 3 tables:
products (id, name)
settings (id, name)
product_setting (product_id, setting_id)
for example: I would like to select only the products you have selected filters!
I do this:
SELECT p. *, s.id as setting
FROM Products p
INNER JOIN product_setting p2 ON (p.id = p2.product_id)
INNER JOIN settings s ON (s.id = p2.setting_id)
WHERE s.id IN (1,2)
but I get all products that have the 'setting' id = 1 OR id = 2.
How to get only those products that have those 'setting' (AND)?
thanks!!
SELECT p.*, s.id as setting
FROM Products p
INNER JOIN product_setting p2 ON (p.id = p2.product_id)
INNER JOIN settings s ON (s.id = p2.setting_id)
WHERE s.id IN (1,2)
GROUP BY p.id
HAVING COUNT(*)=2; // size of IN()
This seems like over kill but...
SELECT p. *, s.id as setting
FROM Products p
INNER JOIN product_setting p2 ON (p.id = p2.product_id)
INNER JOIN settings s ON (s.id = p2.setting_id)
INNER JOIN settings s2 ON (s.id = p2.setting_id)
WHERE
s.id = 1
AND s2.id = 2
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.)