【问题标题】:Select value = 0 if no value to select in SQL Server如果在 SQL Server 中没有要选择的值,则选择值 = 0
【发布时间】:2021-09-21 18:44:17
【问题描述】:

这是我获取总天数的代码

CREATE PROCEDURE [dbo].[hipos_BC_BH_TEST]
    @From_day datetime,
    @To_day datetime
AS
BEGIN
    declare @fd datetime
    set @fd = @From_day

    declare @dt table (Day_get nvarchar(50), Total float)
    
    while @fd <= @To_day
    begin
        insert into @dt
        Select Day_get = Convert(nvarchar(10), @fd, 20), Total = sum(isnull(Total,0))
        from hipos_BH_Info 
        where Convert(nvarchar(10), Day_get, 20) = @fd
        and Cancel_Huy = 0
        group by  Day_get, Total

        set @fd = @fd + 1  --Add 1 day
    end
    Select Day_get, Total = isnull(sum(Total),0)
    from @dt
    group by Day_get
END

从 '2021-09-01' 到 '2021-09-10' 执行后,结果是

Day_get Total
2021-09-01  1106000
2021-09-02  3249600
2021-09-05  316000
2021-09-07  129000
2021-09-08  1547600
2021-09-09  271000
2021-09-10  4765900

我需要它显示日期“2021-09-03”和“2021-09-04”,总 = 0 为

Day_get Total
2021-09-01  1106000
2021-09-02  3249600
2021-09-03  0
2021-09-04  0
2021-09-05  316000
2021-09-07  129000
2021-09-08  1547600
2021-09-09  271000
2021-09-10  4765900

我该怎么办?请帮帮我。

p/s : 我找到了方法,在循环中通过 UNION ALL 添加一个值 = 0 的 cmd 选择

        UNION ALL
        Select Day_get = Convert(nvarchar(10), @fd, 20), Total = 0

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

你永远不应该在循环中做这样的事情。首先,让我们看看如何为您范围内的所有日期生成一个集合:

DECLARE @From_day date = '20210901',
        @To_day   date = '20210910';
  
;WITH n(n) AS 
(
  SELECT 1 UNION ALL SELECT n+1 FROM n
  WHERE n <= DATEDIFF(DAY, @From_day, @To_day)
)
SELECT Day_get = DATEADD(DAY, n-1, @From_day) 
  FROM n ORDER BY Day_get;

结果:

Day_get
----------
2021-09-01
2021-09-02
2021-09-03
2021-09-04
2021-09-05
2021-09-06
2021-09-07
2021-09-08
2021-09-09
2021-09-10

现在您只需左加入那些日子到您表中的数据。所以现在你的(一个!)查询可以变成:

;WITH n(n) AS 
(
  SELECT 1 UNION ALL SELECT n+1 FROM n
  WHERE n <= DATEDIFF(DAY, @From_day, @To_day)
),
d(Day_get) AS 
(
  SELECT DATEADD(DAY, n-1, @From_day) FROM n
)
INSERT INTO @dt(Day_get, Total)
  SELECT d.Day_get, COALESCE(SUM(h.Total),0)
  FROM d
  LEFT OUTER JOIN dbo.hipos_BH_Info AS h
    ON h.Day_get >= d.Day_get
   AND h.Day_get <  DATEADD(DAY, 1, d.Day_get)
   AND h.Cancel_Huy = 0
  GROUP BY d.Day_get;

另外,请不要检查converting dates to a string 的日期匹配并比较字符串,以及always use the schema prefix...

请注意,如果您的日期范围可以超过 100 天,you'll need OPTION (MAXRECURSION n)

【讨论】:

    【解决方案2】:

    只需删除group by并在选择数据时交换isnullsum

    insert into @dt
    Select Day_get = Convert(nvarchar(10), @fd, 20), Total = isnull(sum(Total),0)
    from hipos_BH_Info 
    where Convert(nvarchar(10), Day_get, 20) = @fd
    and Cancel_Huy = 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-08
      • 1970-01-01
      • 2019-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      相关资源
      最近更新 更多