Sql 选择其所有子表行均已选中的父表行
我有两个具有外键关系的表Sql 选择其所有子表行均已选中的父表行,sql,sql-server,query-optimization,Sql,Sql Server,Query Optimization,我有两个具有外键关系的表 Table1 (Parent Table) Id Table2 (Child Table) Tbl2_Id Tbl1_Id (References Table1) OptionName OptonValue 样本数据: 表2包含动态数据,因此它保留用户定义的键/值对 我想使用这个动态数据创建过滤机制。为此,用户将根据表2定义过滤条件。当且仅当使用SELECT语句选择了Table2中的所有子元素时,才会选择Table1中的行 比如, SELECT
Table1 (Parent Table)
Id
Table2 (Child Table)
Tbl2_Id
Tbl1_Id (References Table1)
OptionName
OptonValue
样本数据:
表2
包含动态数据,因此它保留用户定义的键/值对
我想使用这个动态数据创建过滤机制。为此,用户将根据表2
定义过滤条件。当且仅当使用SELECT
语句选择了Table2
中的所有子元素时,才会选择Table1
中的行
比如,
SELECT * from Table2 WHERE (OptionName = "Name" and OptionValue = "John" ) OR (OptionName = "Surname" and OptionValue = "Mach" ) OR (OptionName = "City" and OptionValue = "Manhattan")
假设给定的SELECT返回4行。3行具有Tbl1\u Id=1
,1行具有Tbl1\u Id=2
为Tbl_Id1=1
返回3行,总共有3行具有Tbl_Id1=1
外键关系,因此表1中的第一条记录将选择所有子表行。对于Tbl_Id1=2
只返回1行,但此关系在子表中总共有2条记录。没有为Tbl_Id1=3返回任何行
所以我们必须返回Id=1
表1的row
我正在寻找一种方法来生成这样一个SELECT语句,它返回Table1
中的行,其所有记录都在子表table2
一种可能的方法是在表2.Tbl1_Id
中使用GROUP BY,对分组记录进行计数,然后将该数字与类似的GROUP BY语句进行比较,GROUP BY语句也有WHERE子句来选择拟合记录。返回相同数字的行表示覆盖所有案例
但这对DB来说是一个相当繁重的查询。逻辑是应用程序最常用的功能之一。因此,查询应该尽可能轻松
有没有办法使Dynamic数据过滤更轻松
编辑:样本数据已更改,样本查询为电子书写
-- store the result into temp table
SELECT Tbl2_Id, Tbl1_Id, OptionName, OptionValue
INTO #Resutl1
FROM Table2 WHERE (OptionName = 'Name' and OptionValue = 'John' ) OR .......
SELECT *
FROM #Result1
-- select master table data if all childs are selected..
SELECT *
FROM Table1 t1
WHERE
-- get Ids that are selectable.
EXISTS( SELECT 1
FROM #Resutl1 r
WHERE r.Tbl1_Id = t1.Id
)
-- exclude those which do not have all entries selected.
AND NOT EXISTS( SELECT 1
FROM Table2 t2
LEFT JOIN #Resutl1 r ON t2.Tbl2_Id = r.Tbl2_Id
WHERE t2.Tbl1_Id = t1.Id
AND r.Tbl2_Id IS NULL
)
或者您可以使用GROUP BY as重写最后一个查询
SELECT *
FROM Table1 t1
INNER JOIN (SELECT t2.Tbl1_Id
FROM Table2 t2
LEFT JOIN #Resutl1 r ON t2.Tbl2_Id = r.Tbl2_Id
GROUP BY t2.Tbl1_Id
HAVING COUNT(t2.Tbl2_Id) = COUNT(r.Tbl2_Id)
) ch ON ch.Tbl1_Id = t1.Id
你能给你的样本数据一个样本结果吗?样本数据有点变化,并且给出了sampla查询
SELECT *
FROM Table1 t1
INNER JOIN (SELECT t2.Tbl1_Id
FROM Table2 t2
LEFT JOIN #Resutl1 r ON t2.Tbl2_Id = r.Tbl2_Id
GROUP BY t2.Tbl1_Id
HAVING COUNT(t2.Tbl2_Id) = COUNT(r.Tbl2_Id)
) ch ON ch.Tbl1_Id = t1.Id