这看起来很简单,但是我好几年都没有接触过SQL。当我回来时,完全不喜欢这个数学。假设我有3张桌子,如下所示:
表名:
|NameId| Name |
|------|------|
| 1 | John |
| 2 | Doe |
| 3 | Brian|
表格标签:
|TagId| Tag |
|-----|---------|
| 1 | Teacher |
| 2 | Engineer|
| 3 | Employee|
表名称标签:
|NameId|TagId|
|---- |-----|
|1 | 1 |
|2 | 2 |
|2 | 3 |
|3 | 3 |
我想通过标签找到所有名称以及相关标签。例如。查找带有标签Employee(TagId = 3)的名称。 我希望这样的结果:
|NameId|TagId|
|---- |-----|
|2 | 2 |
|2 | 3 |
|3 | 3 |
如何在T-SQL脚本中实现?
我尝试使用下面的脚本,但是它总是排除记录1 | 1和2 | 2:
SELECT *
FROM NameTag
WHERE TagId = 3
我没想到的结果:
|NameId|TagId|
|---- |-----|
|2 | 3 |
|3 | 3 |
更新
好像有很多解决方案在下面评论为@ plax,@ SteveB或@picklerick以及其他一些指出的解决方案。我没有机会测试所有这些,但它们似乎为我工作。谢谢你们! (今天对我来说是早感恩节。)
那时,我自己也找到了解决方案,并在此处发布以供参考。另外,@ plax在下面指出。
我的解决方案:
--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
@plalx指出的另一种解决方案写得很清楚:
找到所有关联TagID为3的NameId。
SELECT NameId
FROM NameTag
WHERE TagId = 3
找到在步骤1中找到的NameId的所有标签。
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN
(-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3)
答案 0 :(得分:2)
当您无法解决查询问题时,请先将其分解为可以解决的较小问题,然后将较小的解决方案合并在一起。
查找与NameId
相关的TagId
的所有3
。例如
SELECT NameId
FROM NameTag
WHERE TagId = 3
找到在步骤#1中找到的NameId
的所有标签。
SELECT NameId, TagId
FROM NameTag
WHERE NameId IN (
-- Solution from #1
SELECT NameId
FROM NameTag
WHERE TagId = 3
)
如果您随后遇到性能问题,可以从那里开始尝试优化,但是查询的表现力对于可维护性也很重要。
答案 1 :(得分:1)
或者使用相关子查询而不是联接,就像换种猫一样。
SELECT
*
FROM
@NameTag AS nt
WHERE
EXISTS
(
SELECT
1
FROM
@NameTag AS n
WHERE
n.TagId = 3
AND n.NameId = nt.NameId
);
结果:
+--------+-------+
| NameId | TagId |
+--------+-------+
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
+--------+-------+
答案 2 :(得分:1)
Select * from nametag where nameid in(Select nameid from nametag where tagid=3 Group by nameid)
答案 3 :(得分:0)
我认为这可能是您想要的。
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 ;
答案 4 :(得分:0)
您可以在没有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;