【问题标题】:SQL - how to return rows containing ALL children rowsSQL - 如何返回包含所有子行的行
【发布时间】:2012-10-25 02:37:58
【问题描述】:

给定一个父+引用表,其中Reference表如下

Ref_ID    PARENT_ID    
-------------------
1           1            
2           1            
1           2       
3           2       
1           3       
3           3       
4           3       
2           4       
3           4       

我正在尝试返回 ref_id 包含 2 和 3 的所有不同父行

查询

SELECT *
FROM  Parent 
WHERE parent_id in (SELECT parent_id from XRefTable where ref_id in (2, 3) )

返回所有 parent_id 1、2、3、4

WHEREAS 所需的正确结果是返回 parent_id 4,它同时具有 ref_id 的 2 和 3,其他的具有 2 或 3

感谢任何帮助

仅供参考 - 查询中有 4-7 个表(取决于用户选择),因此性能是一个重要因素

SORRY 不能使用存储过程,因为它也必须在 SQL Server CE 上工作

【问题讨论】:

  • 有多少不同的 ref_id 值?还有多少不同的 parent_id 值?您还期望这些会随着时间的推移而增长吗?
  • @Tobsey 这些是用户定义的——根据定义和选择

标签: sql join sql-server-ce


【解决方案1】:
 SELECT parent_id 
 from XRefTable 
 where ref_id in ( 2, 3 ) 
 group by PARENT_ID 
 having count(distinct ref_id) = 2

【讨论】:

  • 看起来不错,关于优化它的任何想法,完整的查询类似于 SELECT * from ParentTable WHERE parent_id in ( ......... ) 目前正在给出样本数据中的成本为 0.0048914,所有相关列都被索引到查询中
  • 对不起,目前我没有进一步提高速度的想法。
【解决方案2】:

你可以这样做:

SELECT 
    ParentReference.Parent_ID
FROM
    ParentReference
    INNER JOIN ParentReference B ON ParentReference.Parent_ID = B.Parent_ID AND ParentReference.Ref_ID = 2 AND B.Ref_ID = 3

【讨论】:

  • 有趣的想法,但当查询在 (2, 3, 5, 7, 8, 10, 12, 15, 18, ....) 中变为 ref_id 时,很快就会变得笨拙
【解决方案3】:

您正在尝试进行逐组比较。为此,我强烈推荐group byhaving 子句:

select parent_id
from Reference r
group by parent_id
having sum(case when ref_id = 2 then 1 else 0 end) > 0 and
       sum(case when ref_id = 3 then 1 else 0 end) > 0

having 子句的每个组件都在计算其中一个字段。逻辑要求两者都存在。

我更喜欢这种方法而不是其他方法的原因是因为您可以使用基本相同的结构来更改逻辑。

如果您有逗号分隔字符串中的列表,则以下内容将起作用。也许不是“优雅”和“关系”,但它有效:

set @Ref_ids = "1,2,3,4"

select parent_id
from Reference r
where charindex(','+cast(ref_id as varchar(255))+',', '+@ref_ids+',') > 0
group by parent_id
having count(distinct ref_id) = (len(replace(@ref_ids, ',', '')) - len(@ref_ids))+1

这是在进行字符串操作以确定 ref_id 是否在列表中。 having 子句然后计算匹配的数量,确保它与列表的大小相同。假设列表中没有空格且没有空白值,这将起作用。

【讨论】:

  • 有趣的想法,但当查询在 (2, 3, 5, 7, 8, 10, 12, 15, 18, ....) 中变为 ref_id 时,很快就会变得笨拙
  • 您的 ref_id 列表是如何存储的?
  • 该表的定义如上,ref_ids 列表是根据用户输入生成的,其中单击 UI 列表中的项目会更新此查询在屏幕上的结果,此外,列表也是用户定义的,所以我们真的不知道查询/ref_ids 中可能有多少项目,因此评论
  • 您是将列表存储在字符串(可能是逗号分隔)还是表格中?
  • 不,( .... ) 中的 ref_id 是根据用户输入生成的,根本不会持久化
猜你喜欢
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-07-23
  • 2017-02-14
  • 2015-09-29
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
相关资源
最近更新 更多