0

我有一个 SELECT CASE 语句限制返回的行数的场景。虽然我不是专业的数据库,但我使用了一些合理的 SQL,并且我不认为 SELECT CASE 实际上会限制结果?如果 WHEN 合格,只需执行 CASE 的 THEN 部分。

为了提供一些背景信息,我有一个事务表,它记录每当一个项目在仓库和客户之间移动时的某些租赁活动。每笔交易都注册为一行,带有参考订单和交易日期。为了在一行上同时获取客户收据交易和返回仓库交易,我使用了(可能是粗略的!)FROM SELECT。但是,这部分似乎还可以。

我在 SQL Server 2012 上。

现在,根据所有这些发生的日期,我获取了所涉及的第一个日期和最后一个日期,并应用了一个 SELECT CASE 来定义一些条件和产生的日期差异计算。

DECLARE @RUNDATE AS DECIMAL(8) = '20170101'
DECLARE @DAYFIRST AS DATETIME = DATEADD(m, DATEDIFF(m, 0, CONVERT(DATE, CAST(@RUNDATE AS VARCHAR(8)), 112)),0)
DECLARE @DAYEND AS DATETIME = DATEADD(s, -1, DATEADD(m, DATEDIFF(m, 0,     CONVERT(DATE, CAST(@RUNDATE AS VARCHAR(8)), 112))+1, 0))
DECLARE @DAYSINPERIOD AS DECIMAL(2) = DAY(EOMONTH(CONVERT(DATE, CAST(@RUNDATE AS     VARCHAR(8)), 112)))

SELECT MTITNO AS 'Item Number',
MTBANO AS 'Serial Number',
MTRORN AS 'Rental Order',
MTRORL AS 'Rental Order Line',
MTTRQT AS 'Delivered Quantity',
CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) AS 'Customer Receipt Date',      --received in M3 to the customer, although this is aligned to when qty left the yard manually by logistics
CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112) AS 'Return To Depot Date',     --last date in the return chain, receiving to the yard.  If still in transit this equals the termination date
CASE
    WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) < @DAYFIRST AND NEXTDATE IS NULL                                            --is started before current period and no return activity or termination
    THEN @DAYSINPERIOD                                                                                                              --simply count the days in the current month as utilised
    ELSE 0
END AS 'On Rent Entire Period',
CASE
    WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) < @DAYFIRST AND NEXTDATE >= @DAYFIRST AND NEXTDATE <= @DAYEND               --is started before current period but has a return activity/termination date
    THEN DATEDIFF("DD",@DAYFIRST,CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112))+1                                                    --difference between start of month and the nextdate (+1 for date difference include all)
    ELSE 0
END AS 'Started Previous Period, Ended This Period',
CASE
    WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) >= @DAYFIRST AND NEXTDATE IS NULL                                           --is started in the current period and no return activity or termination
    THEN DATEDIFF(D,CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112),@DAYEND)+1                                                       --difference between start date and last day of the current month (in line with utilisation) (+1 for date differnce include all)
    ELSE 0
END AS 'Started This Period, No End Date',
CASE
   WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) >= @DAYFIRST AND NEXTDATE >= @DAYFIRST AND NEXTDATE <= @DAYEND               --is started in the current period and has a return activity/termination date
   THEN DATEDIFF(D,CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112),CONVERT(DATE,    CAST(NEXTDATE AS VARCHAR(8)), 112))+1                --different between start date and the nextdate (+1 for date differnce include all)
    ELSE 0
END AS 'Started and Ended This Period',                                                   --current period rental days (should match utilisation as sum of all lines)
@DAYSINPERIOD AS 'Calendar Days in Month',                                        --how many days in the current month
@DAYFIRST AS 'First of Month',                                                    --what is the date of the first day of the current month
@DAYEND AS 'Last of Month'                                                        --what is the date of the last day of the current month
FROM
    (
     SELECT MTITNO,
            MTBANO,
            MTRORN,
            MTRORL,
            MTTRQT,
            MTTRDT,
            (
             SELECT MIN(MTTRDT)
             FROM MVXJDTA.MITTRA T2
             WHERE T1.MTITNO = T2.MTITNO
             AND T1.MTBANO = T2.MTBANO
             AND T1.MTRORN = T2.MTRORN
             AND T1.MTRORL = T2.MTRORL
             AND T1.MTTRQT = T2.MTTRQT
             AND T2.MTTRDT > T1.MTTRDT
             ) AS NEXTDATE
    FROM MVXJDTA.MITTRA T1
    WHERE MTCONO = 880
    AND MTTTYP = '50'
    AND MTTRQT > 0
    AND MTCAMU <> ''
    AND MTRORN LIKE 'A0%'
    ) T

这只会返回整个数据集中的前 2 行。 2 行

但是,如果我注释掉第 4 个 SELECT CASE,那么我会返回所有记录?! 所有行

-- CASE
--    WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) >= @DAYFIRST AND NEXTDATE >= @DAYFIRST AND NEXTDATE <= @DAYEND                --is started in the current period and has a return activity/termination date
--    THEN DATEDIFF(D,CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112),CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112))+1                --different between start date and the nextdate (+1 for date differnce include all)
--     ELSE 0
-- END AS 'Started and Ended This Period',                                                    --current period rental days (should match utilisation as sum of all lines)

奇怪的是第三行应该符合我刚刚注释掉的条件。

谁能帮助我更好地理解为什么 SELECT CASE 会限制返回的行?而我可能的语法错误可能是原因!

4

0 回答 0