3

我有一个查询,无论如何我都想显示行。如果返回了一些数据,查询会返回我需要的正确信息,但是在所有行都为空的情况下,我什么也得不到,显然,如果没有,我需要一行返回全 0,而不是什么都没有。

我曾尝试使用isnull()andcoalesce()来解释这一点,但显然我做得不对。以下是我需要为此目的调整的基本查询。

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
4

3 回答 3

7

一种方法是将表达式包装在 CTE 中,然后UNION ALL使用

UNION ALL SELECT NULL, 0,0,0,0 WHERE NOT EXISTS(SELECT * FROM CTE)

例如

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)

这是一个使用不太复杂的语句的演示

于 2013-01-30T21:59:44.280 回答
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
;

这几乎就像一个交叉连接,但与后者不同的是,它保证返回一个非空数据集。

于 2013-01-30T22:30:57.973 回答
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

sqlfiddlehttp ://sqlfiddle.com/#!6/189a3/1024

于 2013-01-31T09:27:07.277 回答