1

我有一个简单的表:

DECLARE @t TABLE(item INT, itemType INT  )

insert INTO @t SELECT 1000,0
insert INTO @t SELECT 1000,3
insert INTO @t SELECT 1000,5
insert INTO @t SELECT 1000,6
insert INTO @t SELECT 2000,0
insert INTO @t SELECT 2000,3
insert INTO @t SELECT 2000,5
insert INTO @t SELECT 2000,6
insert INTO @t SELECT 3000,0
insert INTO @t SELECT 3000,10
insert INTO @t SELECT 4000,11

我想选择所有项目,itemtype = 3如果有一行,还提供它的基础itemtype如果存在),即itemType = 0

例如 :

  • 对于 itemType = 3

    1000,0应该提供——为什么?因为 table 也有 1000 + itemType 0
    1000,3应该提供 - 为什么?因为我们寻找 itemType=3
    2000,0应该提供 --why ?因为 table 找到了 2000,3 并且这个 2000 也有 itemType=0
    2000,3应该提供--为什么?因为我们寻找 itemType=3

  • 对于 itemType = 10

    3000,0应该提供——为什么?因为表找到了 3000,10 并且这 3000 也有 itemType=0
    3000,10应该提供--为什么?因为我们寻找 itemType=10

  • 对于 itemType = 11

    4000,11应该提供——为什么?因为我们寻找 itemType=11 (注意,没有 itemType 0 ,所以只有它自己)。

我开始做:

;with cte as(
             SELECT * FROM @t  
            )
select * from cte where itemType=3

总之,如果itemType找到了,提供它自己 + 其零类型(如果存在),也提供给他的兄弟姐妹( sample(#1) )

但我不能在union 这里做,因为 CTE 在那里不被识别......垃圾。有可能的。

我该如何解决?

SQL 在线

4

3 回答 3

3

为避免itemType = 3两次评估查询,您可以自外连接然后CROSS APPLY ... VALUES使用UNPIVOT

DECLARE @itemType INT = 3;

WITH T(item1, itemType1, item2, itemType2 )
     AS (SELECT *
         FROM   @t T1
                LEFT JOIN @t T2
                  ON T1.item = T2.item
                     AND T2.itemType = 0
                     AND T1.itemType <> 0
         WHERE  T1.itemType = @itemType) 
SELECT item,
       itemType
FROM   T
       CROSS APPLY ( VALUES (item1, itemType1),
                            (item2, itemType2) ) v(item, itemType) 
WHERE item IS NOT NULL

SQL小提琴

执行计划

计划

于 2013-01-27T15:08:13.363 回答
1
WITH recordList
AS
(
  SELECT item, itemType
  FROM   SampleTable
  WHERE  itemType = 11 -- change here
)
SELECT item, itemType FROM recordList
UNION
SELECT a.item, a.itemType
FROM   SampleTable a
       INNER JOIN recordList b
          ON a.item = b.item
WHERE  a.itemtype = 0
于 2013-01-27T15:09:17.600 回答
1
DECLARE @findtype INT = 3;

WITH results AS
(
  SELECT t.item, @findtype
  FROM   @t t
  WHERE  t.itemType = @findtype
  UNION ALL
  SELECT t.item, 0
  FROM   @t t
         INNER JOIN results r on r.item = t.item
  WHERE  t.itemType = 0
)
SELECT * 
FROM results;
于 2013-01-27T15:11:10.363 回答