3 different tables (1 table associated). When I make a call. the incoming value is replicated - mysql

first table
a.id | a.name
1 | apple
2 | peace
3 | grape
second table
b.id | b.name
1 | yellow
2 | red
3 | green
thidr relationship table
a.id | b.id
1 | 2
1 | 1
3 | 3
3 | 1
2 | 1
I want to see :
...LIKE '%pe%' and tag 'green';
peace green
grape green
This is what I tried:
SELECT *
FROM a
INNER JOIN c ON a.a_id = c.a_id
INNER JOIN b ON c.b_id = b.b_id
WHERE a.a_name LIKE '%pe%'

I'm sure there is better ways to form that query but this seems to get you what you need.
select f.name as fruit, c.name as color from
fruit_color as fc
join fruit as f on f.id = fc.fruit_id
join color as c on c.id = fc.color_id
where f.name like '%pe%' and c.name like '%green%'
Output:
fruit | color
---------------
grape | green
peace | green
sqlFiddle

Related

How to select rows that matches "multiple rows condition" in mysql

So I created a sql fiddle to explain my problem much clearer:
http://sqlfiddle.com/#!9/f35416
As you can see I have 3 tables and 1 of them links the 2 others.
table name: tags
---------------------
id | tag | value
---------------------
1 | color | green
2 | color | yellow
3 | color | red
4 | category | dress
5 | category | car
table name: product_tags_link
---------------------
product_id | tag_id
---------------------
1 | 1
1 | 5
2 | 1
3 | 2
3 | 5
4 | 4
5 | 4
5 | 1
table name: products
---------------------
id | name
---------------------
1 | green car
2 | yellow only
3 | yellow car
4 | dress only
5 | green dress
How can I make it so If I can get whatever product that have a "color" "green" and "category" "car"?
I tried doing:
select `ptl`.`product_id`
from `product_tags_link` as `ptl`
inner join `tags` on `tags`.`id` = `ptl`.`tag_id`
where ((`tags`.`tag` = "green") or (`tags`.`value` = "car"))
but it will return other product that is green OR car. changing it to and will not return anything as well.
I'm hoping to receive is product_id: 1 which have both color:green and category:car
Join all 3 tables, group by product and set the condition in the HAVING clause:
select p.id, p.name
from products p
inner join product_tags_link l on l.product_id = p.id
inner join tags t on t.id = l.tag_id
where (t.tag = 'category' and t.value = 'car')
or (t.tag = 'color' and t.value = 'green')
group by p.id, p.name
having count(distinct t.tag) = 2
Or:
select p.id, p.name
from products p
inner join product_tags_link l on l.product_id = p.id
inner join tags t on t.id = l.tag_id
where (t.tag, t.value) in (('category', 'car'), ('color', 'green'))
group by p.id, p.name
having count(distinct t.tag) = 2
See the demo.
Results:
> id | name
> -: | :---
> 1 | test
I would omit the joining table and do a simple join as follows:
SELECT
p.id AS product_id
FROM
products p
LEFT JOIN
tags t ON p.id = t.id
WHERE
t.value = 'green'
AND p.name LIKE '%car%'

how to get values as per mixed attribute column set for products in sql

I have been struggling to get the desired output from the mysql db. First Please take a look at my table structure
EDIT: HERE IS MY SCHEMA
http://rextester.com/edit/NNCZ7986
Now when i run the below mentioned query, i get the results as below
Select a.prodid,a.product,b.catid,b.category,d.attvalue,c.qty,c.price
from tbl_products a left join
tbl_categories b
on a.catid = b.catid left join
tbl_prodattval c
on a.prodid = c.prodid left join
tbl_attvalues d
on c.attvalid = d.attvalid
Here is the result i get
product K1 which is in green shows right qty and price
and also shows as a separate row
product K1 which is XL with its qty and price
But, i need product K1 which is in green + also XL (Mixed multi attributes) to get the price and quantity
Similarly Tee1 with XL and Green should have 1 qty and price
and Tee1 with XXL with Green should have another
I want results like below (attvalue2 and attvalue3 columns are just imaginary... just to show i want to have product listing from multi attribute)
Prodid | Product | catid | category | attvalue | attvalue2 | attvalue3 | qty | price
20 | Tee1 | 14 | Tees | Green | XL | | 2 | 23.00
20 | Tee1 | 14 | Tees | Blue | XL | | 2 | 21.00
How do i get it?
Thanks in advance
Select a.prodid,a.product,b.catid,b.category,d.attvalue, e.attvalue,c.qty,c.price
from tbl_products a
left join tbl_categories b
on a.catid = b.catid
left join tbl_prodattval c
on a.prodid = c.prodid
left join tbl_attvalues d
on c.attvalid = d.attvalid
and d.attID = //in tbl_attributes what is attid for color (ID for color)
left join tbl_attvalues e
on c.attvalidid = e.attvalid
and d.attID = //'in tbl_attributes what is attid for size (ID for size)

How to get total "active" users using Mysql?

I have four tables:
Table A: users_table
Table B: users_account_table
Table C: fangates_table
Table D: downloads_table
Table A(users_table) contains three columns: ID, NAME and GATE_COUNT.
Table C(fangates_table) contains users gates.
Table D(downloads_table) contains fangates_table_id and account_id.
TABLE A
ID | NAME | GATE_COUNT
---------------------------
1 | Joy | 2
---------------------------
2 | Ash | 0
---------------------------
3 | Nik | 2
---------------------------
4 | Wox | 0
TABLE B
ID | A_ID | ACCOUNT_ID
---------------------------
1 | 1 | 123456
---------------------------
2 | 1 | 654321
---------------------------
3 | 3 | 5888
---------------------------
4 | 3 | 8787
TABLE C
ID | A_ID | TITLE
---------------------------
1 | 1 | ABCD
---------------------------
2 | 1 | DFCV
---------------------------
3 | 3 | FGTG
---------------------------
4 | 3 | FRGTG
TABLE D
ID | C_ID | ACCOUNT_ID
---------------------------
1 | 1 | 123456
---------------------------
2 | 2 | 123456
---------------------------
3 | 3 | 7859
---------------------------
4 | 1 | 7585
From the above tables, I am trying to get the total "active" users (where an active user is defined as a user with fangates having any downloads other not themself)
I have tried the following query, but it has failed.
SELECT COUNT(*) FROM D
WHERE (C_ID,ACCOUNT_ID)
NOT IN
(SELECT C.ID, B.ACCOUNT_ID FROM A
LEFT JOIN B ON A.ID = B.A_ID
LEFT JOIN C ON A.ID = C.A_ID
WHERE A.GATE_COUNT >0);
The error, as I see it, is that you are failing to provide a join parameter in the initial selection of your table. If I am to understand your table design correctly, the following query would retrieve all the information in your tables:
SELECT *
FROM A,B,C,D
WHERE B.A_ID = A.ID AND C.A_ID = A.ID AND D.C_ID = C.ID;
If my presumption is correct, and you are trying to get the active users, you could simply place your parameters as an appended AND and continue onward. However, doing this many joins could greatly slow down any code; joins are a very taxing process, no matter how small the tables are. Since you are looking to find the count of downloads
SELECT COUNT(*) FROM D
WHERE (C_ID)
NOT IN
(SELECT C.ID FROM A, C
WHERE GATE_COUNT >0 AND A.ID = C.A_ID);
From what I can tell, you don't need to specify the distinct ACCOUNT_ID from the B table, as the information is distinctly paired to the B table. Otherwise, your columns would mismatch.
Otherwise, you can do a second lookup and try adding the B lookup as an AND parameter
SELECT COUNT(*) FROM D
WHERE (C_ID)
NOT IN (SELECT C.ID FROM A, C
WHERE GATE_COUNT >0 AND A.ID = C.A_ID) AND ACCOUNT_ID NOT IN
(SELECT DISTINCT B.ACCOUNT_ID FROM A,B WHERE A.ID = B.A_ID AND A.GATE_COUNT >0);
SELECT COUNT(DISTINCT(B.A_ID))
FROM TABLE_B B
JOIN TABLE_C C ON (B.A_ID = C.A_ID)
JOIN TABLE_D D ON (D.C_ID = C.C_ID AND B.ACCOUNT_ID <> D.ACCOUNT_ID)

MYSQL joining 2 tables accross multiple fields

It should be oh so simple, but perhaps the wine has gone to my head.
Table A (things that need parts)
id | Name | part1 | part2 | part 3 | part 4 | etc
1 | This thing | 1 | 2 | 3 | 2 | etc
2 | another thing | 1 | 1 | 4 | 5 | etc
3 | even more | 11 | 2 | 2 | 2 | etc
Table B (parts)
id | Description
1 | I am a part
2 | I am another Part
3 | Im a very imprtant part
A;; i actually need to do is select all the "parts" that each "thing" needs by its "DESCRIPTION"
so I get a each line in English rather than ID no's
ie
id | Thing name | part 1 | part 2 | part 3 | part 4
1 | This Thing | name of part | name of part | name of part | name of part
Like i said, complete memory overload here and Ive lost the will to live. Any help very gratefull recieved. Thanks in advance.
It will look something like this. Its been a while since I wrote a MySQL query. I am sure somebody could improve on it.
SELECT
a.id,
a.name,
b1.description,
b2.description,
b3.description,
b4.description
FROM
table_a `a`
LEFT JOIN
table_b `b1`
ON a.part1 = b1.id
LEFT JOIN
table_b `b2`
ON a.part2 = b2.id
LEFT JOIN
table_b `b3`
ON a.part3 = b3.id
LEFT JOIN
table_b `b4`
ON a.part4 = b4.id
Your data model has doomed you to complexity from the start.
select
*
from TableA A
left join TableB B1 on A.part1 = B1.id
left join TableB B2 on A.part2 = B1.id
left join TableB B3 on A.part3 = B1.id
left join TableB B4 on A.part4 = B1.id
This is untested, but if you "unpivot" TableA many more possibilities open up.
e.g.
SELECT
A.id
, A.Name
, GROUP_CONCAT(B.Description ORDER BY A.rowno) as PartsList
FROM (
SELECT
A1.id
, A1.Name
, cj.rowno
, CASE
WHEN cj.rowno = 1 THEN part1
WHEN cj.rowno = 2 THEN part2
WHEN cj.rowno = 3 THEN part3
WHEN cj.rowno = 4 THEN part4
END AS LinkID
FROM TableA a1
CROSS JOIN ( 1 AS rowno
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) cj
) A
LEFT JOIN TableB B ON A.LinkId = B.ID
GROUP BY
A.id
, A.Name
and, if TableA was normalized permanently you would not need these complexities.

MySQl return records that match AND/OR against second table values

This is such a basic question but for some reason all my knowledge of SQL has just exit the building. Three basic tables:
Table A
id | name
---------
1 | John
2 | Mike
3 | Henry
4 | Cooper
Table B
id | tag
---------
1 | chocolate
2 | ice cream
3 | cookies
and a table which joins the two:
Table C
id | name_id | tag_id
---------------------
1 | 1 | 2
2 | 1 | 3
3 | 2 | 1
4 | 3 | 2
5 | 3 | 3
I want to find the people who like BOTH chocolate and cookies. The following gives me all the people that like chocolate and cookies, but I only want the people who like both (chocolate AND cookies instead of chocolate OR cookies).
SELECT name FROM tablea a JOIN tablec c ON a.id = c.name_id WHERE c.tag_id IN (1,3)
The following obviously doesn't work:
SELECT name FROM tablea a JOIN tablec c ON a.id = c.name_id WHERE c.tag_id = 1 AND c.tag_id = 3 GROUP BY name
but it's essentially what I want. Also, I'd like to do this without involving the tableb in the JOIN, because where I'm using this there will be various other tables joined in and I don't want to confuse the picture. This has got to be so simple!
One hackish method:
SELECT name, COUNT(c.tag_id) AS cnt
FROM tablea a
JOIN tablec c ON a.id = c.name_id
WHERE c.tag_id IN (1,3)
GROUP BY name
HAVING cnt = 2
Count up how many preferences each user has (which would be limited to chocolate or cookies via the where clause), and then return only those users which have 2 preferences.
The easiest and fastest way is to join the tablec twice, one for chocolates and the other for cookies
select name
from tablea a
inner join tablec chocolates on a.id = chocolates.name_id
inner join tablec cookies on a.id = cookies.name_id
where chocolates.tag_id = 1
and cookies.tag_id = 3