TSQL - How to get a record satisfies a condition without excluding others that do not
up vote
0
down vote
favorite
It seems pretty simple but I have not touched SQL for years. When I come back , totally stuck with this math. Let say I have 3 tables as below:
Table Name:
|NameId| Name |
|------|------|
| 1 | John |
| 2 | Doe |
| 3 | Brian|
Table Tag:
|TagId| Tag |
|-----|---------|
| 1 | Teacher |
| 2 | Engineer|
| 3 | Employee|
Table NameTag:
|NameId|TagId|
|---- |-----|
|1 | 1 |
|2 | 2 |
|2 | 3 |
|3 | 3 |
I want to find all names along with associated tags by a tag. E.g. find names with tag Employee (TagId = 3). I expect result like this:
|NameId|TagId|
|---- |-----|
|2 | 2 |
|2 | 3 |
|3 | 3 |
How can I achieve that in a T-SQL script?
I tried with script below but it always excludes the records 1|1 and 2|2:
SELECT *
FROM NameTag
WHERE TagId = 3
Result I do not expect:
|NameId|TagId|
|---- |-----|
|2 | 3 |
|3 | 3 |
UPDATE
Looks like there are many solutions commented below as @plax, @SteveB or @picklerick and some others pointed. I have not had a chance to test all of them but they seem working for me. Thank you all! (early thanksgiving today for me).
By that time, I have also found a solution myself and posted here for reference. Also, @plax pointed out below.
My solution:
--Get persons that have the tag.
WITH Person_CTE AS
(
SELECT DISTINCT NameId
FROM NameTag
WHERE TagId = 3
)
-- Looking other tags for the person.
SELECT *
FROM NameTag nt
JOIN Person_CTE p ON nt.NameId = p.NameId
Another solution as @plalx has pointed out that was written very clearly:
Find all NameId that have an associated TagId of 3. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for NameId we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN
(-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3)
sql sql-server tsql
add a comment |
up vote
0
down vote
favorite
It seems pretty simple but I have not touched SQL for years. When I come back , totally stuck with this math. Let say I have 3 tables as below:
Table Name:
|NameId| Name |
|------|------|
| 1 | John |
| 2 | Doe |
| 3 | Brian|
Table Tag:
|TagId| Tag |
|-----|---------|
| 1 | Teacher |
| 2 | Engineer|
| 3 | Employee|
Table NameTag:
|NameId|TagId|
|---- |-----|
|1 | 1 |
|2 | 2 |
|2 | 3 |
|3 | 3 |
I want to find all names along with associated tags by a tag. E.g. find names with tag Employee (TagId = 3). I expect result like this:
|NameId|TagId|
|---- |-----|
|2 | 2 |
|2 | 3 |
|3 | 3 |
How can I achieve that in a T-SQL script?
I tried with script below but it always excludes the records 1|1 and 2|2:
SELECT *
FROM NameTag
WHERE TagId = 3
Result I do not expect:
|NameId|TagId|
|---- |-----|
|2 | 3 |
|3 | 3 |
UPDATE
Looks like there are many solutions commented below as @plax, @SteveB or @picklerick and some others pointed. I have not had a chance to test all of them but they seem working for me. Thank you all! (early thanksgiving today for me).
By that time, I have also found a solution myself and posted here for reference. Also, @plax pointed out below.
My solution:
--Get persons that have the tag.
WITH Person_CTE AS
(
SELECT DISTINCT NameId
FROM NameTag
WHERE TagId = 3
)
-- Looking other tags for the person.
SELECT *
FROM NameTag nt
JOIN Person_CTE p ON nt.NameId = p.NameId
Another solution as @plalx has pointed out that was written very clearly:
Find all NameId that have an associated TagId of 3. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for NameId we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN
(-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3)
sql sql-server tsql
So you want a resultset with All names for a tag and all the tags for those names?
– SteveB
Nov 21 at 21:26
So... What are the results that you DO want?
– Jason A. Long
Nov 21 at 21:27
@SteveB: yes, I do want that.
– Thang Nguyen
Nov 21 at 23:08
@JasonA.Long: I did say in the post.
– Thang Nguyen
Nov 21 at 23:08
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
It seems pretty simple but I have not touched SQL for years. When I come back , totally stuck with this math. Let say I have 3 tables as below:
Table Name:
|NameId| Name |
|------|------|
| 1 | John |
| 2 | Doe |
| 3 | Brian|
Table Tag:
|TagId| Tag |
|-----|---------|
| 1 | Teacher |
| 2 | Engineer|
| 3 | Employee|
Table NameTag:
|NameId|TagId|
|---- |-----|
|1 | 1 |
|2 | 2 |
|2 | 3 |
|3 | 3 |
I want to find all names along with associated tags by a tag. E.g. find names with tag Employee (TagId = 3). I expect result like this:
|NameId|TagId|
|---- |-----|
|2 | 2 |
|2 | 3 |
|3 | 3 |
How can I achieve that in a T-SQL script?
I tried with script below but it always excludes the records 1|1 and 2|2:
SELECT *
FROM NameTag
WHERE TagId = 3
Result I do not expect:
|NameId|TagId|
|---- |-----|
|2 | 3 |
|3 | 3 |
UPDATE
Looks like there are many solutions commented below as @plax, @SteveB or @picklerick and some others pointed. I have not had a chance to test all of them but they seem working for me. Thank you all! (early thanksgiving today for me).
By that time, I have also found a solution myself and posted here for reference. Also, @plax pointed out below.
My solution:
--Get persons that have the tag.
WITH Person_CTE AS
(
SELECT DISTINCT NameId
FROM NameTag
WHERE TagId = 3
)
-- Looking other tags for the person.
SELECT *
FROM NameTag nt
JOIN Person_CTE p ON nt.NameId = p.NameId
Another solution as @plalx has pointed out that was written very clearly:
Find all NameId that have an associated TagId of 3. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for NameId we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN
(-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3)
sql sql-server tsql
It seems pretty simple but I have not touched SQL for years. When I come back , totally stuck with this math. Let say I have 3 tables as below:
Table Name:
|NameId| Name |
|------|------|
| 1 | John |
| 2 | Doe |
| 3 | Brian|
Table Tag:
|TagId| Tag |
|-----|---------|
| 1 | Teacher |
| 2 | Engineer|
| 3 | Employee|
Table NameTag:
|NameId|TagId|
|---- |-----|
|1 | 1 |
|2 | 2 |
|2 | 3 |
|3 | 3 |
I want to find all names along with associated tags by a tag. E.g. find names with tag Employee (TagId = 3). I expect result like this:
|NameId|TagId|
|---- |-----|
|2 | 2 |
|2 | 3 |
|3 | 3 |
How can I achieve that in a T-SQL script?
I tried with script below but it always excludes the records 1|1 and 2|2:
SELECT *
FROM NameTag
WHERE TagId = 3
Result I do not expect:
|NameId|TagId|
|---- |-----|
|2 | 3 |
|3 | 3 |
UPDATE
Looks like there are many solutions commented below as @plax, @SteveB or @picklerick and some others pointed. I have not had a chance to test all of them but they seem working for me. Thank you all! (early thanksgiving today for me).
By that time, I have also found a solution myself and posted here for reference. Also, @plax pointed out below.
My solution:
--Get persons that have the tag.
WITH Person_CTE AS
(
SELECT DISTINCT NameId
FROM NameTag
WHERE TagId = 3
)
-- Looking other tags for the person.
SELECT *
FROM NameTag nt
JOIN Person_CTE p ON nt.NameId = p.NameId
Another solution as @plalx has pointed out that was written very clearly:
Find all NameId that have an associated TagId of 3. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for NameId we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN
(-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3)
sql sql-server tsql
sql sql-server tsql
edited Nov 22 at 5:19
marc_s
566k12610931245
566k12610931245
asked Nov 21 at 20:58
Thang Nguyen
134
134
So you want a resultset with All names for a tag and all the tags for those names?
– SteveB
Nov 21 at 21:26
So... What are the results that you DO want?
– Jason A. Long
Nov 21 at 21:27
@SteveB: yes, I do want that.
– Thang Nguyen
Nov 21 at 23:08
@JasonA.Long: I did say in the post.
– Thang Nguyen
Nov 21 at 23:08
add a comment |
So you want a resultset with All names for a tag and all the tags for those names?
– SteveB
Nov 21 at 21:26
So... What are the results that you DO want?
– Jason A. Long
Nov 21 at 21:27
@SteveB: yes, I do want that.
– Thang Nguyen
Nov 21 at 23:08
@JasonA.Long: I did say in the post.
– Thang Nguyen
Nov 21 at 23:08
So you want a resultset with All names for a tag and all the tags for those names?
– SteveB
Nov 21 at 21:26
So you want a resultset with All names for a tag and all the tags for those names?
– SteveB
Nov 21 at 21:26
So... What are the results that you DO want?
– Jason A. Long
Nov 21 at 21:27
So... What are the results that you DO want?
– Jason A. Long
Nov 21 at 21:27
@SteveB: yes, I do want that.
– Thang Nguyen
Nov 21 at 23:08
@SteveB: yes, I do want that.
– Thang Nguyen
Nov 21 at 23:08
@JasonA.Long: I did say in the post.
– Thang Nguyen
Nov 21 at 23:08
@JasonA.Long: I did say in the post.
– Thang Nguyen
Nov 21 at 23:08
add a comment |
5 Answers
5
active
oldest
votes
up vote
2
down vote
accepted
When you can't work out a query problem, first break it down into smaller problems you can solve and then merge the smaller solutions together.
Find all
NameId
that have an associatedTagId
of3
. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for
NameId
we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN (
-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3
)
If you then run into performance issues you can start from there and try to optimize, but the expressiveness of the query is also important for maintainability.
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given(NameId, TagId)
pairs are unique already, so you will not have duplicateNameId
with the conditionWHERE TadId = 3
. I had made the same mistake originally in my answer.
– plalx
Nov 22 at 2:18
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
|
show 1 more comment
up vote
1
down vote
Or with a correlated subquery instead of a join, just as another way to skin that cat.
SELECT
*
FROM
@NameTag AS nt
WHERE
EXISTS
(
SELECT
1
FROM
@NameTag AS n
WHERE
n.TagId = 3
AND n.NameId = nt.NameId
);
Results:
+--------+-------+
| NameId | TagId |
+--------+-------+
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
+--------+-------+
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
add a comment |
up vote
1
down vote
Select * from nametag where nameid in(Select nameid from nametag where tagid=3 Group by nameid)
New contributor
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
Good, Glad to help!
– picklerick
Nov 22 at 6:59
add a comment |
up vote
0
down vote
I think this might be what you are looking for.
DECLARE @NameTag TABLE (NameId int, TagId int)
INSERT INTO @NameTag SELECT 1, 1
INSERT INTO @NameTag SELECT 2, 2
INSERT INTO @NameTag SELECT 2, 3
INSERT INTO @NameTag SELECT 3, 3
SELECT a2.*
FROM @NameTag a1
JOIN @NameTag a2 on a1.NameId = a2.NameId
WHERE a1.TagId = 3 ;
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
@ThangNguyen It only works because any constraint on a specific singleTagId
is guaranteed to return uniqueNameId
s.a1
will refer to all uniqueNameId
s whereTagId = 3
and theJOIN
essentially acts as theIN
clause in my answer. I prefer theIN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something likeTagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.
– plalx
Nov 22 at 2:26
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
add a comment |
up vote
0
down vote
You can do this without a join
:
select nt.*
from (select nt.*,
sum(case when tagid = 3 then 1 else 0 end) over (partition by nameid) as cnt_3
from nametag nt
) nt
where cnt_3 > 0;
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen The solution adds the aggregated SUM of rows whereTagId = 3
, partitioned byNameId
, meaning all rows with the sameNameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner ifcnt_3
would have been namedinclude_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.
– plalx
Nov 22 at 2:38
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
add a comment |
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
When you can't work out a query problem, first break it down into smaller problems you can solve and then merge the smaller solutions together.
Find all
NameId
that have an associatedTagId
of3
. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for
NameId
we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN (
-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3
)
If you then run into performance issues you can start from there and try to optimize, but the expressiveness of the query is also important for maintainability.
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given(NameId, TagId)
pairs are unique already, so you will not have duplicateNameId
with the conditionWHERE TadId = 3
. I had made the same mistake originally in my answer.
– plalx
Nov 22 at 2:18
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
|
show 1 more comment
up vote
2
down vote
accepted
When you can't work out a query problem, first break it down into smaller problems you can solve and then merge the smaller solutions together.
Find all
NameId
that have an associatedTagId
of3
. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for
NameId
we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN (
-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3
)
If you then run into performance issues you can start from there and try to optimize, but the expressiveness of the query is also important for maintainability.
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given(NameId, TagId)
pairs are unique already, so you will not have duplicateNameId
with the conditionWHERE TadId = 3
. I had made the same mistake originally in my answer.
– plalx
Nov 22 at 2:18
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
|
show 1 more comment
up vote
2
down vote
accepted
up vote
2
down vote
accepted
When you can't work out a query problem, first break it down into smaller problems you can solve and then merge the smaller solutions together.
Find all
NameId
that have an associatedTagId
of3
. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for
NameId
we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN (
-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3
)
If you then run into performance issues you can start from there and try to optimize, but the expressiveness of the query is also important for maintainability.
When you can't work out a query problem, first break it down into smaller problems you can solve and then merge the smaller solutions together.
Find all
NameId
that have an associatedTagId
of3
. E.g.
SELECT NameId
FROM NameTag
WHERE TagId = 3
Find all tags for
NameId
we found in step #1.
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN (
-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3
)
If you then run into performance issues you can start from there and try to optimize, but the expressiveness of the query is also important for maintainability.
answered Nov 21 at 21:58
plalx
32k44770
32k44770
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given(NameId, TagId)
pairs are unique already, so you will not have duplicateNameId
with the conditionWHERE TadId = 3
. I had made the same mistake originally in my answer.
– plalx
Nov 22 at 2:18
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
|
show 1 more comment
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given(NameId, TagId)
pairs are unique already, so you will not have duplicateNameId
with the conditionWHERE TadId = 3
. I had made the same mistake originally in my answer.
– plalx
Nov 22 at 2:18
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
I had found a solution myself before I looked back this answer. Plus how you describe to solve the problem. Much appreciated! I also posted my solution above.
– Thang Nguyen
Nov 21 at 23:06
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given
(NameId, TagId)
pairs are unique already, so you will not have duplicate NameId
with the condition WHERE TadId = 3
. I had made the same mistake originally in my answer.– plalx
Nov 22 at 2:18
Great! I'm glad you had found a solution. In your solution you dont need the DISTINCT keyword in there given
(NameId, TagId)
pairs are unique already, so you will not have duplicate NameId
with the condition WHERE TadId = 3
. I had made the same mistake originally in my answer.– plalx
Nov 22 at 2:18
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
Actually, there is an Id for table NameTag. I forgot to include it.
– Thang Nguyen
Nov 23 at 16:28
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
@ThangNguyen I'm not sure I understand how your comment relates to mine? :P
– plalx
Nov 23 at 16:33
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
it does need the DISTINCT keyword because NameId and TagId are not unique. Sorry to not mention that :D.
– Thang Nguyen
Nov 23 at 22:43
|
show 1 more comment
up vote
1
down vote
Or with a correlated subquery instead of a join, just as another way to skin that cat.
SELECT
*
FROM
@NameTag AS nt
WHERE
EXISTS
(
SELECT
1
FROM
@NameTag AS n
WHERE
n.TagId = 3
AND n.NameId = nt.NameId
);
Results:
+--------+-------+
| NameId | TagId |
+--------+-------+
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
+--------+-------+
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
add a comment |
up vote
1
down vote
Or with a correlated subquery instead of a join, just as another way to skin that cat.
SELECT
*
FROM
@NameTag AS nt
WHERE
EXISTS
(
SELECT
1
FROM
@NameTag AS n
WHERE
n.TagId = 3
AND n.NameId = nt.NameId
);
Results:
+--------+-------+
| NameId | TagId |
+--------+-------+
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
+--------+-------+
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
add a comment |
up vote
1
down vote
up vote
1
down vote
Or with a correlated subquery instead of a join, just as another way to skin that cat.
SELECT
*
FROM
@NameTag AS nt
WHERE
EXISTS
(
SELECT
1
FROM
@NameTag AS n
WHERE
n.TagId = 3
AND n.NameId = nt.NameId
);
Results:
+--------+-------+
| NameId | TagId |
+--------+-------+
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
+--------+-------+
Or with a correlated subquery instead of a join, just as another way to skin that cat.
SELECT
*
FROM
@NameTag AS nt
WHERE
EXISTS
(
SELECT
1
FROM
@NameTag AS n
WHERE
n.TagId = 3
AND n.NameId = nt.NameId
);
Results:
+--------+-------+
| NameId | TagId |
+--------+-------+
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
+--------+-------+
answered Nov 21 at 21:40
Eric Brandt
1,8151518
1,8151518
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
add a comment |
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
This works for me as well. And yes, whenever it works, it's always good. But if I have more choices, I would prefer not choose a nested select. Just IMO. Thanks!
– Thang Nguyen
Nov 23 at 22:49
add a comment |
up vote
1
down vote
Select * from nametag where nameid in(Select nameid from nametag where tagid=3 Group by nameid)
New contributor
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
Good, Glad to help!
– picklerick
Nov 22 at 6:59
add a comment |
up vote
1
down vote
Select * from nametag where nameid in(Select nameid from nametag where tagid=3 Group by nameid)
New contributor
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
Good, Glad to help!
– picklerick
Nov 22 at 6:59
add a comment |
up vote
1
down vote
up vote
1
down vote
Select * from nametag where nameid in(Select nameid from nametag where tagid=3 Group by nameid)
New contributor
Select * from nametag where nameid in(Select nameid from nametag where tagid=3 Group by nameid)
New contributor
edited Nov 21 at 22:47
New contributor
answered Nov 21 at 22:37
picklerick
849
849
New contributor
New contributor
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
Good, Glad to help!
– picklerick
Nov 22 at 6:59
add a comment |
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
Good, Glad to help!
– picklerick
Nov 22 at 6:59
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
That works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:34
Good, Glad to help!
– picklerick
Nov 22 at 6:59
Good, Glad to help!
– picklerick
Nov 22 at 6:59
add a comment |
up vote
0
down vote
I think this might be what you are looking for.
DECLARE @NameTag TABLE (NameId int, TagId int)
INSERT INTO @NameTag SELECT 1, 1
INSERT INTO @NameTag SELECT 2, 2
INSERT INTO @NameTag SELECT 2, 3
INSERT INTO @NameTag SELECT 3, 3
SELECT a2.*
FROM @NameTag a1
JOIN @NameTag a2 on a1.NameId = a2.NameId
WHERE a1.TagId = 3 ;
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
@ThangNguyen It only works because any constraint on a specific singleTagId
is guaranteed to return uniqueNameId
s.a1
will refer to all uniqueNameId
s whereTagId = 3
and theJOIN
essentially acts as theIN
clause in my answer. I prefer theIN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something likeTagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.
– plalx
Nov 22 at 2:26
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
add a comment |
up vote
0
down vote
I think this might be what you are looking for.
DECLARE @NameTag TABLE (NameId int, TagId int)
INSERT INTO @NameTag SELECT 1, 1
INSERT INTO @NameTag SELECT 2, 2
INSERT INTO @NameTag SELECT 2, 3
INSERT INTO @NameTag SELECT 3, 3
SELECT a2.*
FROM @NameTag a1
JOIN @NameTag a2 on a1.NameId = a2.NameId
WHERE a1.TagId = 3 ;
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
@ThangNguyen It only works because any constraint on a specific singleTagId
is guaranteed to return uniqueNameId
s.a1
will refer to all uniqueNameId
s whereTagId = 3
and theJOIN
essentially acts as theIN
clause in my answer. I prefer theIN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something likeTagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.
– plalx
Nov 22 at 2:26
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
add a comment |
up vote
0
down vote
up vote
0
down vote
I think this might be what you are looking for.
DECLARE @NameTag TABLE (NameId int, TagId int)
INSERT INTO @NameTag SELECT 1, 1
INSERT INTO @NameTag SELECT 2, 2
INSERT INTO @NameTag SELECT 2, 3
INSERT INTO @NameTag SELECT 3, 3
SELECT a2.*
FROM @NameTag a1
JOIN @NameTag a2 on a1.NameId = a2.NameId
WHERE a1.TagId = 3 ;
I think this might be what you are looking for.
DECLARE @NameTag TABLE (NameId int, TagId int)
INSERT INTO @NameTag SELECT 1, 1
INSERT INTO @NameTag SELECT 2, 2
INSERT INTO @NameTag SELECT 2, 3
INSERT INTO @NameTag SELECT 3, 3
SELECT a2.*
FROM @NameTag a1
JOIN @NameTag a2 on a1.NameId = a2.NameId
WHERE a1.TagId = 3 ;
answered Nov 21 at 21:34
SteveB
551214
551214
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
@ThangNguyen It only works because any constraint on a specific singleTagId
is guaranteed to return uniqueNameId
s.a1
will refer to all uniqueNameId
s whereTagId = 3
and theJOIN
essentially acts as theIN
clause in my answer. I prefer theIN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something likeTagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.
– plalx
Nov 22 at 2:26
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
add a comment |
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
@ThangNguyen It only works because any constraint on a specific singleTagId
is guaranteed to return uniqueNameId
s.a1
will refer to all uniqueNameId
s whereTagId = 3
and theJOIN
essentially acts as theIN
clause in my answer. I prefer theIN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something likeTagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.
– plalx
Nov 22 at 2:26
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
It looks like a very clever solution despite I have not fully tested yet. I will look at it.
– Thang Nguyen
Nov 21 at 23:25
@ThangNguyen It only works because any constraint on a specific single
TagId
is guaranteed to return unique NameId
s. a1
will refer to all unique NameId
s where TagId = 3
and the JOIN
essentially acts as the IN
clause in my answer. I prefer the IN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something like TagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.– plalx
Nov 22 at 2:26
@ThangNguyen It only works because any constraint on a specific single
TagId
is guaranteed to return unique NameId
s. a1
will refer to all unique NameId
s where TagId = 3
and the JOIN
essentially acts as the IN
clause in my answer. I prefer the IN
clause given it's closer to the semantics of what we want to achieve. Furthermore the solution would return duplicates if the initial condition is changed for something like TagId IN (2, 3)
. Both solutions should have a similar execution plan and that's a good one as well.– plalx
Nov 22 at 2:26
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
@plalx I agree that the IN is a more easily readable solution and I like that. We just try to avoid it if the results of the inner query can get rather large because we have seen performance issue with it. We usually replace it with an EXISTS query or a JOIN if possible. I really wish the more easily readable version of the query was ALWAYS the fastest query. In this example you are completely right and I should have included it as well as the EXISTS version.
– SteveB
Nov 23 at 17:39
add a comment |
up vote
0
down vote
You can do this without a join
:
select nt.*
from (select nt.*,
sum(case when tagid = 3 then 1 else 0 end) over (partition by nameid) as cnt_3
from nametag nt
) nt
where cnt_3 > 0;
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen The solution adds the aggregated SUM of rows whereTagId = 3
, partitioned byNameId
, meaning all rows with the sameNameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner ifcnt_3
would have been namedinclude_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.
– plalx
Nov 22 at 2:38
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
add a comment |
up vote
0
down vote
You can do this without a join
:
select nt.*
from (select nt.*,
sum(case when tagid = 3 then 1 else 0 end) over (partition by nameid) as cnt_3
from nametag nt
) nt
where cnt_3 > 0;
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen The solution adds the aggregated SUM of rows whereTagId = 3
, partitioned byNameId
, meaning all rows with the sameNameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner ifcnt_3
would have been namedinclude_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.
– plalx
Nov 22 at 2:38
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
add a comment |
up vote
0
down vote
up vote
0
down vote
You can do this without a join
:
select nt.*
from (select nt.*,
sum(case when tagid = 3 then 1 else 0 end) over (partition by nameid) as cnt_3
from nametag nt
) nt
where cnt_3 > 0;
You can do this without a join
:
select nt.*
from (select nt.*,
sum(case when tagid = 3 then 1 else 0 end) over (partition by nameid) as cnt_3
from nametag nt
) nt
where cnt_3 > 0;
answered Nov 21 at 22:41
Gordon Linoff
746k33285390
746k33285390
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen The solution adds the aggregated SUM of rows whereTagId = 3
, partitioned byNameId
, meaning all rows with the sameNameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner ifcnt_3
would have been namedinclude_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.
– plalx
Nov 22 at 2:38
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
add a comment |
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen The solution adds the aggregated SUM of rows whereTagId = 3
, partitioned byNameId
, meaning all rows with the sameNameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner ifcnt_3
would have been namedinclude_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.
– plalx
Nov 22 at 2:38
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
It seems a little bit complex but it works for me. Thanks!
– Thang Nguyen
Nov 21 at 23:36
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen . . . I have no idea why you would think this is complex.
– Gordon Linoff
Nov 22 at 0:33
@ThangNguyen The solution adds the aggregated SUM of rows where
TagId = 3
, partitioned by NameId
, meaning all rows with the same NameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner if cnt_3
would have been named include_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.– plalx
Nov 22 at 2:38
@ThangNguyen The solution adds the aggregated SUM of rows where
TagId = 3
, partitioned by NameId
, meaning all rows with the same NameId
will end up with the same SUM. It then only keeps the rows where the SUM is > 0. It could have been cleaner if cnt_3
would have been named include_row
IMO, given it's a bit really: the count would never be greater than 1 in this scenario. It's also a very unintuitive way of solving the problem IMO. Unless it yields any performance benefits that you need I'd keep things simple.– plalx
Nov 22 at 2:38
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
Thanks for explaining, plalx. @Gordon: honestly I have just had an overlook but it's working. Thanks!
– Thang Nguyen
Nov 23 at 16:13
add a comment |
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%2f53420386%2ftsql-how-to-get-a-record-satisfies-a-condition-without-excluding-others-that-d%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
So you want a resultset with All names for a tag and all the tags for those names?
– SteveB
Nov 21 at 21:26
So... What are the results that you DO want?
– Jason A. Long
Nov 21 at 21:27
@SteveB: yes, I do want that.
– Thang Nguyen
Nov 21 at 23:08
@JasonA.Long: I did say in the post.
– Thang Nguyen
Nov 21 at 23:08