我需要帮助为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'
这是目前的结果:
我希望没有结果的人在我的结果集中仍然有记录。我不明白如何只为一列使用distinct。 DISTINCT仅适用于整行,但由于UNION,行当然不同。
答案 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
如果你想重新编写你的查询,它应该如下(对不起,我没有构建表来测试它,但你可以尝试自己)
; 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