我有一个查询,我试图显示行,无论如何。如果返回了一些数据,查询会返回正确的信息,但是如果所有行都为空,我显然什么都没有,而且没有什么,如果没有,我需要一行返回0。
我尝试使用isnull()
和coalesce()
来解释这一点,但显然我做得不对。下面是我需要为此目的调整的基本查询。
SELECT
Vendor
,SUM(TotalAssigned) as 'Total Production Assigned Not Completed'
,SUM(AssignedFees) as 'Work in process Fees'
,SUM(TotalSubmitted) as 'Total Production Submitted'
,SUM(SubmittedFees) as 'Submitted Production Fees'
FROM(
SELECT
distinct
v.ContactFirstName+' '+v.ContactLastName AS Vendor
,oi.orderid, oi.orderitemid
,CASE WHEN oi.QueueID > 0 and oi.lastmilestoneid < 70 THEN 1 ELSE 0 END AS TotalAssigned
,CASE WHEN oi.QueueID > 0 and oi.lastmilestoneid < 70 THEN dbo.GetAdjustedVendorFee(oi.OrderID, oi.OrderItemID) END AS AssignedFees
,CASE WHEN oim.MilestoneID = 70 THEN 1 ELSE 0 END AS TotalSubmitted
,CASE WHEN oim.MilestoneID = 70 THEN dbo.GetAdjustedVendorFee(oi.OrderID, oi.OrderItemID) END AS SubmittedFees
FROM
OrderItems oi
LEFT JOIN OrderItemMilestones oim ON oim.OrderID = oi.OrderID and oim.OrderItemID = oi.OrderItemID
LEFT JOIN Vendors v ON v.VendorID = oi.VendorID
WHERE
oim.MilestoneDate BETWEEN dbo.TruncateDate(dateadd(dd, -1, Current_Timestamp)) and dbo.TruncateDate(Current_Timestamp)
and oi.VendorID in (105144)
and oi.productid not in (105)
)x
GROUP BY Vendor
答案 0 :(得分:6)
一种方法是将表达式包装在CTE中,然后使用
UNION ALL
UNION ALL SELECT NULL, 0,0,0,0 WHERE NOT EXISTS(SELECT * FROM CTE)
e.g。
WITH CTE AS
(SELECT
Vendor
,SUM(TotalAssigned) as 'Total Production Assigned Not Completed'
,SUM(AssignedFees) as 'Work in process Fees'
,SUM(TotalSubmitted) as 'Total Production Submitted'
,SUM(SubmittedFees) as 'Submitted Production Fees'
FROM(
SELECT
distinct
v.ContactFirstName+' '+v.ContactLastName AS Vendor
,oi.orderid, oi.orderitemid
,CASE WHEN oi.QueueID > 0 and oi.lastmilestoneid < 70 THEN 1 ELSE 0 END AS TotalAssigned
,CASE WHEN oi.QueueID > 0 and oi.lastmilestoneid < 70 THEN dbo.GetAdjustedVendorFee(oi.OrderID, oi.OrderItemID) END AS AssignedFees
,CASE WHEN oim.MilestoneID = 70 THEN 1 ELSE 0 END AS TotalSubmitted
,CASE WHEN oim.MilestoneID = 70 THEN dbo.GetAdjustedVendorFee(oi.OrderID, oi.OrderItemID) END AS SubmittedFees
FROM
OrderItems oi
LEFT JOIN OrderItemMilestones oim ON oim.OrderID = oi.OrderID and oim.OrderItemID = oi.OrderItemID
LEFT JOIN Vendors v ON v.VendorID = oi.VendorID
WHERE
oim.MilestoneDate BETWEEN dbo.TruncateDate(dateadd(dd, -1, Current_Timestamp)) and dbo.TruncateDate(Current_Timestamp)
and oi.VendorID in (105144)
and oi.productid not in (105)
)x
GROUP BY Vendor)
SELECT * FROM CTE
UNION ALL SELECT NULL, 0,0,0,0 WHERE NOT EXISTS(SELECT * FROM CTE)
这里的a demo语句不太复杂
答案 1 :(得分:2)
另一种方法可以是将查询作为派生表加入,无条件地连接到一行默认值,并使用ISNULL或COALESCE从子查询返回数据或回退到默认值:
SELECT
ISNULL(sub.Vendor , def.Vendor ) AS Vendor
,ISNULL(sub.[Total Production Assigned Not Completed], def.[Total Production Assigned Not Completed]) AS 'Total Production Assigned Not Completed'
,ISNULL(sub.[Work in process Fees] , def.[Work in process Fees] ) AS 'Work in process Fees'
,ISNULL(sub.[Total Production Submitted] , def.[Total Production Submitted] ) AS 'Total Production Submitted'
,ISNULL(sub.[Submitted Production Fees] , def.[Submitted Production Fees] ) AS 'Submitted Production Fees'
FROM (
SELECT
'' AS Vendor
,0 AS 'Total Production Assigned Not Completed'
,0 AS 'Work in process Fees'
,0 AS 'Total Production Submitted'
,0 AS 'Submitted Production Fees'
) def
LEFT JOIN (
your query
) sub
ON 1=1 -- unconditionally; almost the same as CROSS JOIN
;
这几乎就像交叉连接,但与后者不同,保证返回非空数据集。
答案 2 :(得分:2)
这可以是一个更简单的解决方案(@AndriyM的混音):
SELECT
Vendor
,SUM(TotalAssigned) as 'Total Production Assigned Not Completed'
,SUM(AssignedFees) as 'Work in process Fees'
,SUM(TotalSubmitted) as 'Total Production Submitted'
,SUM(SubmittedFees) as 'Submitted Production Fees'
FROM (
SELECT
distinct
v.ContactFirstName+' '+v.ContactLastName AS Vendor
,oi.orderid, oi.orderitemid
,CASE WHEN oi.QueueID > 0 and oi.lastmilestoneid < 70 THEN 1 ELSE 0 END AS TotalAssigned
,CASE WHEN oi.QueueID > 0 and oi.lastmilestoneid < 70 THEN dbo.GetAdjustedVendorFee(oi.OrderID, oi.OrderItemID) END AS AssignedFees
,CASE WHEN oim.MilestoneID = 70 THEN 1 ELSE 0 END AS TotalSubmitted
,CASE WHEN oim.MilestoneID = 70 THEN dbo.GetAdjustedVendorFee(oi.OrderID, oi.OrderItemID) END AS SubmittedFees
FROM
OrderItems oi
LEFT JOIN OrderItemMilestones oim ON oim.OrderID = oi.OrderID and oim.OrderItemID = oi.OrderItemID
LEFT JOIN Vendors v ON v.VendorID = oi.VendorID
WHERE
oim.MilestoneDate BETWEEN dbo.TruncateDate(dateadd(dd, -1, Current_Timestamp)) and dbo.TruncateDate(Current_Timestamp)
and oi.VendorID in (105144)
and oi.productid not in (105)
) x RIGHT JOIN (SELECT 1 as ONE) T ON 1=1
GROUP BY Vendor
sqlfiddle :http://sqlfiddle.com/#!6/189a3/1024