Many-To-Many select only rows with exactly same tags
I have 3 tables: tags, products and relation table between them.
Relation table looks for example like this:
tagId | ProductId
1 | 1
2 | 1
2 | 9
The user can pick two options "All of these" or "One of these".
So if user picks All of these, it's means that the product must have exactly all of tags which the user chose.
So if user pick tags with id 1 and 2, it should select only product with id 1, because this product has exactly the same tags the user chose. (Another way is if the user picks the tag with id 2, it should select only product with id 9.)
So, the product has to have all tags which the user chose (no more, no less).
SQL that I already have for Any/One of these:
SELECT DISTINCT s.SKU
FROM SKUToEAN as s
LEFT JOIN ProductDetails as p ON s.ProductDetailID=p.id
JOIN ProductTagRelation as ptr ON (ptr.productId=p.id and ptr.tagId IN(Ids of selected tags))
Example behavior:
TagId = 1 it should select => None
TagId = 2 it should select => 9
TagId = 1,2 it should select = 1,9
So probably I need two queries. One for any/one of these ( I already have this one ) and the second for all of these.
With PHP I decide which query to use.
mysql many-to-many
add a comment |
I have 3 tables: tags, products and relation table between them.
Relation table looks for example like this:
tagId | ProductId
1 | 1
2 | 1
2 | 9
The user can pick two options "All of these" or "One of these".
So if user picks All of these, it's means that the product must have exactly all of tags which the user chose.
So if user pick tags with id 1 and 2, it should select only product with id 1, because this product has exactly the same tags the user chose. (Another way is if the user picks the tag with id 2, it should select only product with id 9.)
So, the product has to have all tags which the user chose (no more, no less).
SQL that I already have for Any/One of these:
SELECT DISTINCT s.SKU
FROM SKUToEAN as s
LEFT JOIN ProductDetails as p ON s.ProductDetailID=p.id
JOIN ProductTagRelation as ptr ON (ptr.productId=p.id and ptr.tagId IN(Ids of selected tags))
Example behavior:
TagId = 1 it should select => None
TagId = 2 it should select => 9
TagId = 1,2 it should select = 1,9
So probably I need two queries. One for any/one of these ( I already have this one ) and the second for all of these.
With PHP I decide which query to use.
mysql many-to-many
2
You said "not more, not less". When you search for 1,2, expected result is not 1? 9 only has tag 2 (missing tag 1).
– DanB
Nov 15 '18 at 20:07
add a comment |
I have 3 tables: tags, products and relation table between them.
Relation table looks for example like this:
tagId | ProductId
1 | 1
2 | 1
2 | 9
The user can pick two options "All of these" or "One of these".
So if user picks All of these, it's means that the product must have exactly all of tags which the user chose.
So if user pick tags with id 1 and 2, it should select only product with id 1, because this product has exactly the same tags the user chose. (Another way is if the user picks the tag with id 2, it should select only product with id 9.)
So, the product has to have all tags which the user chose (no more, no less).
SQL that I already have for Any/One of these:
SELECT DISTINCT s.SKU
FROM SKUToEAN as s
LEFT JOIN ProductDetails as p ON s.ProductDetailID=p.id
JOIN ProductTagRelation as ptr ON (ptr.productId=p.id and ptr.tagId IN(Ids of selected tags))
Example behavior:
TagId = 1 it should select => None
TagId = 2 it should select => 9
TagId = 1,2 it should select = 1,9
So probably I need two queries. One for any/one of these ( I already have this one ) and the second for all of these.
With PHP I decide which query to use.
mysql many-to-many
I have 3 tables: tags, products and relation table between them.
Relation table looks for example like this:
tagId | ProductId
1 | 1
2 | 1
2 | 9
The user can pick two options "All of these" or "One of these".
So if user picks All of these, it's means that the product must have exactly all of tags which the user chose.
So if user pick tags with id 1 and 2, it should select only product with id 1, because this product has exactly the same tags the user chose. (Another way is if the user picks the tag with id 2, it should select only product with id 9.)
So, the product has to have all tags which the user chose (no more, no less).
SQL that I already have for Any/One of these:
SELECT DISTINCT s.SKU
FROM SKUToEAN as s
LEFT JOIN ProductDetails as p ON s.ProductDetailID=p.id
JOIN ProductTagRelation as ptr ON (ptr.productId=p.id and ptr.tagId IN(Ids of selected tags))
Example behavior:
TagId = 1 it should select => None
TagId = 2 it should select => 9
TagId = 1,2 it should select = 1,9
So probably I need two queries. One for any/one of these ( I already have this one ) and the second for all of these.
With PHP I decide which query to use.
mysql many-to-many
mysql many-to-many
edited Nov 16 '18 at 6:29
BSMP
2,62952536
2,62952536
asked Nov 15 '18 at 19:15
Frederik FakoFrederik Fako
83
83
2
You said "not more, not less". When you search for 1,2, expected result is not 1? 9 only has tag 2 (missing tag 1).
– DanB
Nov 15 '18 at 20:07
add a comment |
2
You said "not more, not less". When you search for 1,2, expected result is not 1? 9 only has tag 2 (missing tag 1).
– DanB
Nov 15 '18 at 20:07
2
2
You said "not more, not less". When you search for 1,2, expected result is not 1? 9 only has tag 2 (missing tag 1).
– DanB
Nov 15 '18 at 20:07
You said "not more, not less". When you search for 1,2, expected result is not 1? 9 only has tag 2 (missing tag 1).
– DanB
Nov 15 '18 at 20:07
add a comment |
2 Answers
2
active
oldest
votes
You can GROUP BY
on the ProductID
and use conditional aggregation based filtering inside the Having
clause. MySQL automatically casts boolean values to 0/1 when using in numeric context. So, in order to have a specific tagID
value available against a ProductID
, its SUM(tagId = ..)
should be 1.
All of these:
SELECT ptr.productId, s.SKU
FROM SKUToEAN AS s
LEFT JOIN ProductDetails AS p
ON p.id = s.ProductDetailID
JOIN ProductTagRelation AS ptr
ON ptr.productId = p.id
GROUP BY ptr.productId, s.SKU
HAVING SUM(ptr.tagID = 1) AND -- 1 should be there
SUM(ptr.tagID = 2) AND -- 2 should be there
NOT SUM(ptr.tagID NOT IN (1,2)) -- other than 1,2 should not be there
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
1
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
|
show 1 more comment
Is this you are looking for (for all condition)?
select product.id
from products
inner join <table> on products.id = <table>.productId
group by product.id
having group_concat(<table>.tagId order by <table>.tagId separator ',') = '1,2';
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
This should do the tricks. If you search 1 and 2, search ='1,2'
;
– DanB
Nov 15 '18 at 20:05
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53326477%2fmany-to-many-select-only-rows-with-exactly-same-tags%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can GROUP BY
on the ProductID
and use conditional aggregation based filtering inside the Having
clause. MySQL automatically casts boolean values to 0/1 when using in numeric context. So, in order to have a specific tagID
value available against a ProductID
, its SUM(tagId = ..)
should be 1.
All of these:
SELECT ptr.productId, s.SKU
FROM SKUToEAN AS s
LEFT JOIN ProductDetails AS p
ON p.id = s.ProductDetailID
JOIN ProductTagRelation AS ptr
ON ptr.productId = p.id
GROUP BY ptr.productId, s.SKU
HAVING SUM(ptr.tagID = 1) AND -- 1 should be there
SUM(ptr.tagID = 2) AND -- 2 should be there
NOT SUM(ptr.tagID NOT IN (1,2)) -- other than 1,2 should not be there
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
1
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
|
show 1 more comment
You can GROUP BY
on the ProductID
and use conditional aggregation based filtering inside the Having
clause. MySQL automatically casts boolean values to 0/1 when using in numeric context. So, in order to have a specific tagID
value available against a ProductID
, its SUM(tagId = ..)
should be 1.
All of these:
SELECT ptr.productId, s.SKU
FROM SKUToEAN AS s
LEFT JOIN ProductDetails AS p
ON p.id = s.ProductDetailID
JOIN ProductTagRelation AS ptr
ON ptr.productId = p.id
GROUP BY ptr.productId, s.SKU
HAVING SUM(ptr.tagID = 1) AND -- 1 should be there
SUM(ptr.tagID = 2) AND -- 2 should be there
NOT SUM(ptr.tagID NOT IN (1,2)) -- other than 1,2 should not be there
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
1
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
|
show 1 more comment
You can GROUP BY
on the ProductID
and use conditional aggregation based filtering inside the Having
clause. MySQL automatically casts boolean values to 0/1 when using in numeric context. So, in order to have a specific tagID
value available against a ProductID
, its SUM(tagId = ..)
should be 1.
All of these:
SELECT ptr.productId, s.SKU
FROM SKUToEAN AS s
LEFT JOIN ProductDetails AS p
ON p.id = s.ProductDetailID
JOIN ProductTagRelation AS ptr
ON ptr.productId = p.id
GROUP BY ptr.productId, s.SKU
HAVING SUM(ptr.tagID = 1) AND -- 1 should be there
SUM(ptr.tagID = 2) AND -- 2 should be there
NOT SUM(ptr.tagID NOT IN (1,2)) -- other than 1,2 should not be there
You can GROUP BY
on the ProductID
and use conditional aggregation based filtering inside the Having
clause. MySQL automatically casts boolean values to 0/1 when using in numeric context. So, in order to have a specific tagID
value available against a ProductID
, its SUM(tagId = ..)
should be 1.
All of these:
SELECT ptr.productId, s.SKU
FROM SKUToEAN AS s
LEFT JOIN ProductDetails AS p
ON p.id = s.ProductDetailID
JOIN ProductTagRelation AS ptr
ON ptr.productId = p.id
GROUP BY ptr.productId, s.SKU
HAVING SUM(ptr.tagID = 1) AND -- 1 should be there
SUM(ptr.tagID = 2) AND -- 2 should be there
NOT SUM(ptr.tagID NOT IN (1,2)) -- other than 1,2 should not be there
edited Nov 15 '18 at 20:04
answered Nov 15 '18 at 19:19
Madhur BhaiyaMadhur Bhaiya
19.6k62236
19.6k62236
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
1
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
|
show 1 more comment
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
1
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
@FrederikFako please edit the question and add this there. I will modify my answer accordingly.
– Madhur Bhaiya
Nov 15 '18 at 19:45
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
I edited my question can you look at it now?
– Frederik Fako
Nov 15 '18 at 19:57
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
@FrederikFako please note that queries will be different for the two cases.
– Madhur Bhaiya
Nov 15 '18 at 20:02
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
Im using PHP if clause to decide which querie use. Im sorry for my English, I hope I understood what you mean
– Frederik Fako
Nov 15 '18 at 20:06
1
1
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
Jep, i think this is what I need. Thanks you very much!
– Frederik Fako
Nov 15 '18 at 20:10
|
show 1 more comment
Is this you are looking for (for all condition)?
select product.id
from products
inner join <table> on products.id = <table>.productId
group by product.id
having group_concat(<table>.tagId order by <table>.tagId separator ',') = '1,2';
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
This should do the tricks. If you search 1 and 2, search ='1,2'
;
– DanB
Nov 15 '18 at 20:05
add a comment |
Is this you are looking for (for all condition)?
select product.id
from products
inner join <table> on products.id = <table>.productId
group by product.id
having group_concat(<table>.tagId order by <table>.tagId separator ',') = '1,2';
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
This should do the tricks. If you search 1 and 2, search ='1,2'
;
– DanB
Nov 15 '18 at 20:05
add a comment |
Is this you are looking for (for all condition)?
select product.id
from products
inner join <table> on products.id = <table>.productId
group by product.id
having group_concat(<table>.tagId order by <table>.tagId separator ',') = '1,2';
Is this you are looking for (for all condition)?
select product.id
from products
inner join <table> on products.id = <table>.productId
group by product.id
having group_concat(<table>.tagId order by <table>.tagId separator ',') = '1,2';
edited Nov 15 '18 at 20:05
answered Nov 15 '18 at 19:21
DanBDanB
1,7521315
1,7521315
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
This should do the tricks. If you search 1 and 2, search ='1,2'
;
– DanB
Nov 15 '18 at 20:05
add a comment |
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
This should do the tricks. If you search 1 and 2, search ='1,2'
;
– DanB
Nov 15 '18 at 20:05
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
I edited my question can you look at it now? I only want Exaclly All of these. Any/One of these I already has.
– Frederik Fako
Nov 15 '18 at 20:03
This should do the tricks. If you search 1 and 2, search =
'1,2'
;– DanB
Nov 15 '18 at 20:05
This should do the tricks. If you search 1 and 2, search =
'1,2'
;– DanB
Nov 15 '18 at 20:05
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53326477%2fmany-to-many-select-only-rows-with-exactly-same-tags%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
You said "not more, not less". When you search for 1,2, expected result is not 1? 9 only has tag 2 (missing tag 1).
– DanB
Nov 15 '18 at 20:07