如何使用属性查看表B中是否存在表A中的所有记录?

时间:2016-08-07 19:52:41

标签: sql sql-server

我有一个表,其中包含用户列表,用户列表编号(1,2,3 ...)以及该特定列表中包含的treasure_no。

我有另一个表“LookingFor”(Treasure和User之间的连接表),用于存储寻宝(F-FOUND,NF - NOT FOUND,NM-NEED MAINTENANCE)字段的状态:User_name,Treasure_NO,Status

我正在努力寻找那些在他们的名单中拥有所有宝藏的人(宝藏_不是fk to table Treasure)他们在“LookingFor”表中找到他们 (找到的条件定义为F OR NM)。 并且他们有2个或更多不同的列表(可以按每个用户的列表编号隔离)

我的代码现在是这样的:

SELECT LF.user_detail_Name
            FROM(SELECT LC.user_name_detail AS NAME,LC.tressure_No AS T_NO,LC.num_Of_List_User AS LIST_NO
                 FROM dbo.tblListContains AS LC ) AS LIST INNER JOIN dbo.tblLookingFor AS LF
            ON LIST.NAME = LF.user_detail_Name

           WHERE LIST.NAME NOT IN(SELECT LIST3.user_name_detail
                                            FROM(SELECT LC.user_name_detail,LC.tressure_No
                                             From dbo.tblListContains as LC

                                              EXCEPT

                                              SELECT LF.user_detail_Name,LF.tressure_No
                                              FROM dbo.tblLookingFor AS LF)AS LIST3)

           AND LIST.NAME IN (SELECT LIST4.user_name_detail
                             FROM(SELECT LC.user_name_detail,LC.tressure_No
                                 From dbo.tblListContains as LC

                                              INTERSECT

                                              SELECT LF.user_detail_Name,LF.tressure_No
                                              FROM dbo.tblLookingFor AS LF
                                              WHERE LF.Status_finding = 'F' OR
                                              LF.Status_finding = 'NM')AS LIST4)

           GROUP BY LF.user_detail_Name
           HAVING (COUNT(DISTINCT LIST.LIST_NO))>=2

我的问题是,我无法确保有人在他的名单中添加的每一件宝贝都被他找到了,如果我可以让这个团体被隔离,并且只是询问我现在是否正在查看他的记录(在table ListContains)就在这个组中我已经完成了。

我想要的例子:

ON TblListContains有以下条目:

AAA(用户名单),1(用户名单),1(TREASURE_NO)

AAA,2,2-

AAA,1,3-

BBB,1,2-

ON TblLookingFor有以下条目:

1(宝藏号),AAA(用户名),F(状态),测试(评论),07/08/2016(日期),2(用户排名的藏身水平),3(地形水平)

2,AAA,NM,testing2,07 / 08 / 2016,2,4

3,AAA,F,testing3,07 / 08 / 2016,2,4

2,BBB,NF,testing4,07 / 08 / 2016,2,4

我想只返回AAA(因为他至少有2个名单并且在他的名单中找到了所有的宝藏)

为方便起见,我还会添加表格方案:

table scheme

有什么建议吗?

谢谢, 汤姆

2 个答案:

答案 0 :(得分:0)

我想我可能会把它放在一起。

这是我提出的解决方案:

   SELECT LIST.NAME
            FROM(SELECT LC.user_name_detail AS NAME,LC.tressure_No AS T_NO,LC.num_Of_List_User AS LIST_NO
                 FROM dbo.tblListContains AS LC ) AS LIST 

           WHERE LIST.NAME IN  (SELECT LIST4.user_name_detail
                             FROM(SELECT LC.user_name_detail,LC.tressure_No
                                 From dbo.tblListContains as LC

                                              INTERSECT

                                              SELECT LF.user_detail_Name,LF.tressure_No
                                              FROM dbo.tblLookingFor AS LF
                                              WHERE LF.Status_finding = 'F' OR
                                              LF.Status_finding = 'NM')AS LIST4 INNER JOIN
                                              dbo.tblListContains AS LC
                                              ON LIST4.user_name_detail = LC.user_name_detail
                                              AND LIST4.tressure_No = LC.tressure_No
                                            GROUP BY LIST4.user_name_detail
                                    HAVING COUNT(LIST4.tressure_No) = (SELECT COUNT(LC.tressure_No)
                                                                       FROM dbo.tblListContains AS LC
                                                                       WHERE LIST4.user_name_detail = LC.user_name_detail))                                       
GROUP BY LIST.NAME
HAVING (COUNT(DISTINCT LIST.LIST_NO))>=2 

答案 1 :(得分:0)

如果我理解你的请求,我们只需要加入所有"找到" LF记录到LC记录。然后我们按用户分组并检查......

  • 是否所有LC记录都有"找到" LF记录和
  • 列表数量是否至少为2。

以下是查询:

select lc.user_name_detail
from dbo.tbllistcontains lc
left join dbo.tbllookingfor lf on  lf.user_name_detail =  lc.user_name_detail
                               and lf.tressure_no      =  lc.tressure_no
                               and lf.status_finding   in ('F', 'NM')
group by lc.user_name_detail
having count(*) = count(lf.user_name_detail) -- all found
and count(distinct lf.list_no) >= 2; -- two or more lists