T-SQL在不符合搜索条件的记录上检索具有默认值的行

时间:2018-03-23 20:55:05

标签: sql-server tsql

我需要帮助为WHERE子句中不符合我的搜索条件的记录设置默认值。 WHERE子句可以在每次运行时动态构建,因此有时买家不会在结果集中,但我希望记录显示0的计数和值。

SELECT COUNT(DISTINCT h.PONum) AS unconfirmedCount,
   ISNULL(SUM(d.DocExtCost), 0) AS unconfirmedValue,
    CASE v.Buyer_c
        WHEN 'Person5' THEN 'Person4'
        ELSE v.Buyer_c
     END AS buyerID    

FROM [Dbo].POHeader AS h

INNER JOIN [Dbo].PODetail AS d
        ON (h.Company = d.Company AND 
            h.PONum = d.PONum)

INNER JOIN [Dbo].Vendor AS v
        ON (h.Company = v.Company AND 
            h.VendorNum = v.VendorNum) 

WHERE h.FirstPublishedToPortal_c < DATEADD(HOUR, 24, GETDATE())
     AND v.Buyer_c IN ('Person1', 'Person2', 'Person3', 'Person4', 'Person5')
     AND h.ReadyForSupplierPortal_c = 1
     AND ( h.Confirmed = 0 OR h.Confirmed IS NULL )

 GROUP BY CASE v.Buyer_c
             WHEN 'Person5' THEN 'Person4'
             ELSE v.Buyer_c
          END             

 UNION SELECT 0, 0, 'Person1'
 UNION SELECT 0, 0, 'Person2'
 UNION SELECT 0, 0, 'Person3'
 UNION SELECT 0, 0, 'Person4'

这是目前的结果:

enter image description here

这是我想要的结果集:
enter image description here

我希望没有结果的人在我的结果集中仍然有记录。我不明白如何只为一列使用distinct。 DISTINCT仅适用于整行,但由于UNION,行当然不同。

5 个答案:

答案 0 :(得分:1)

你可以用这种方式涂抹这种猫。首先,您可以在原始聚合中包含所有用户。将where子句中的内容放入case语句中以进行求和。 e.g。

...sum(case when <your where clause stuff evaulates true> then null else d.DocExtCost end)...

然后你仍然得到所有的买家,但是他们的价值被淘汰(因此用你的isnull()评价为0。

或者,您可以预先获取所有买家的列表,可以是临时表,也可以使用派生表进行内联。然后,您可以将该组用户加入到您现在拥有的聚合中(当然不包括联合行)并执行isnull(aggregate.SumDocExtCost, 0)

答案 1 :(得分:1)

为了简化答案,我假设您的结果(在那个大的SELECT中)可以在一个表中(例如,您可以使用CTE来封装您的SELECT查询)。考虑到这一点,这是结果(将#s视为您的大SELECT结果)

create table #s ([Count] int, [Value] int, [BuyerID] varchar(10))

insert into #s values (1, 250, 'Person1'), (1, 285, 'Person2'), (1, 1560, 'Person3')


select [UnconfirmedCount]=(isnull(s.[count],0)+ t.[count]) 
, [UnconfirmedValue]=isnull(s.[value],0)+t.[value],
, buyerID = case when s.BuyerID is not null then s.BuyerID else t.BuyerID end 
from #s s
right join (values (0, 0, 'Person1'), (0, 0, 'Person2'), (0, 0, 'Person3'), (0, 0, 'Person4')) T([Count], [Value], [BuyerID] ) 
on s.BuyerID = t.BuyerID

enter image description here

如果你想重新编写你的查询,它应该如下(对不起,我没有构建表来测试它,但你可以尝试自己)

; with s ([Count], [Value], buyerID) as
(
SELECT COUNT(DISTINCT h.PONum) AS unconfirmedCount,
   ISNULL(SUM(d.DocExtCost), 0) AS unconfirmedValue,
    CASE v.Buyer_c
        WHEN 'Person5' THEN 'Person4'
        ELSE v.Buyer_c
     END AS buyerID    

FROM [Dbo].POHeader AS h

INNER JOIN [Dbo].PODetail AS d
        ON (h.Company = d.Company AND 
            h.PONum = d.PONum)

INNER JOIN [Dbo].Vendor AS v
        ON (h.Company = v.Company AND 
            h.VendorNum = v.VendorNum) 

WHERE h.FirstPublishedToPortal_c < DATEADD(HOUR, 24, GETDATE())
     AND v.Buyer_c IN ('Person1', 'Person2', 'Person3', 'Person4', 'Person5')
     AND h.ReadyForSupplierPortal_c = 1
     AND ( h.Confirmed = 0 OR h.Confirmed IS NULL )

 GROUP BY CASE v.Buyer_c
             WHEN 'Person5' THEN 'Person4'
             ELSE v.Buyer_c
          END             
)
select [UnconfirmedCount]=(isnull(s.[count],0)+ t.[count]), [UnconfirmedValue]=isnull(s.[value],0)+t.[value]
, buyerID = case when s.BuyerID is not null then s.BuyerID else t.BuyerID end 
from  s
right join (values (0, 0, 'Person1'), (0, 0, 'Person2'), (0, 0, 'Person3'), (0, 0, 'Person4')) T([Count], [Value], [BuyerID] ) 
on s.BuyerID = t.BuyerID

答案 2 :(得分:1)

使用CTE(通用表格表达式):

  ;With buyers AS (BuyerId)
  ( 
     -- Select Distinct BuyerID
  ),

  unconfirmedCounts AS (UnconfirmedCount, UnconfirmedValue, BuyerId)
  ( 
      -- Select Counts & Value for each Buyer where available
  )

  Select ISNULL(u.UnconfirmedCount,0) AS UnconfirmedCount,
         ISNULL(u.UnconfirmedValue,0) AS UnconfirmedValue,
         b.BuyerId as BuyerId
 FROM buyers b
 LEFT JOIN unconfirmedCounts u on b.BuyerId = u.BuyerId;

答案 3 :(得分:0)

使用不LEFT JOIN

UNION ALL

答案 4 :(得分:0)

忘记Info.plist中的case。我不相信这是有效的。如果您需要映射“Person5”和“#39;到#4; Person4&#39;然后用表和连接

来做

为什么选择PODetail?你没有使用它。

group by