【问题标题】:How to conditionally execute the FROM clause in a SELECT statement?如何有条件地执行 SELECT 语句中的 FROM 子句?
【发布时间】:2019-01-27 04:10:44
【问题描述】:

我有四个间隔:

Hourly
Daily
Monthly
Yearly

这些对应于四个表值函数:

Hourly(@Date, @Hour)
Daily(@Date)
Monthly(@Date)
Yearly(@Date)

接下来,我有一个 SSRS 参数@Interval,其值等于上述四个区间之一。那么根据参数的值,我需要调用相应的函数。

我已经尝试过这些方面的东西,但它当然不会解析:

SELECT * FROM
CASE
  WHEN @Interval = 'Hourly'   THEN (SELECT * FROM dbo.Hourly(@Date, @Hour)  AS Result)
  WHEN @Interval = 'Daily'    THEN (SELECT * FROM dbo.Daily(@Date)          AS Result)
  WHEN @Interval = 'Monthly'  THEN (SELECT * FROM dbo.Monthly(@Date)        AS Result)
  WHEN @Interval = 'Yearly'   THEN (SELECT * FROM dbo.Yearly(@Date)         AS Result)
END

当我在 SSRS 数据集中使用它时,它必须是单行 SQL 语句。

我运气不好?我是否必须重新考虑我的架构,还是可以在一个声明中完成?

--编辑--

根据请求,我将包含函数的 TSQL 代码。每个都调用另一个,一直到Yearly,作为一种重载结构。

每小时(@Date,@Hour)

CREATE FUNCTION [dbo].[Hourly]
(   
    @Date DATETIME,
    @Hour INT
)
RETURNS TABLE 
AS
RETURN
(
  SELECT * FROM [Daily](@Date)
    WHERE
      DATEPART(HOUR, [LogTime]) = @Hour
)

每日(@Date)

CREATE FUNCTION [dbo].[Daily]
(   
    @Date DATETIME
)
RETURNS TABLE 
AS
RETURN
(
  SELECT * FROM [Monthly](@Date)
    WHERE
      DATEPART(DAY, [OffsetTime]) = DATEPART(DAY, @Date)
)

每月(@Date)

CREATE FUNCTION [dbo].[Monthly]
(   
    @Date DATETIME
)
RETURNS TABLE 
AS
RETURN
(
  SELECT * FROM [Yearly](@Date)
    WHERE
      DATEPART(MONTH, [OffsetTime]) = DATEPART(MONTH, @Date)
)

每年(@Date)

CREATE FUNCTION [dbo].[Yearly]
(   
    @Date DATETIME
)
RETURNS TABLE 
AS
RETURN
(
  SELECT TOP 100 PERCENT * FROM [LogEntries]
    WHERE DATEPART(YEAR, [OffsetTime]) = DATEPART(YEAR, @Date)
    ORDER BY [OffsetTime]
)

【问题讨论】:

  • 是否所有函数都返回相同形状的表格,例如列的编号顺序和类型?
  • 也显示功能,所有功能也可以更改为单个功能
  • @stickybit ~ 是的,这是一种“重载”类型的设计,每个较低的函数都会调用它上面的函数,直到我们到达 Yearly。你有什么想法?
  • @PSK ~ 我添加了这些功能。我对您将它们结合起来的想法非常感兴趣。

标签: sql-server tsql reporting-services


【解决方案1】:

我可以建议有一个单一的功能,如下所示。

CREATE FUNCTION [dbo].[GetData]
(   
    @Date DATETIME,
    @Hour INT,
    @Mode VARCHAR(10)
)
RETURNS TABLE 
AS
RETURN
(

     SELECT *  FROM [LogEntries]
        WHERE 
        (DATEPART(YEAR, [OffsetTime]) = DATEPART(YEAR, @Date) AND @Mode='Yearly')
        OR
        (DATEPART(MONTH, [OffsetTime]) = DATEPART(MONTH, @Date) AND @Mode='Monthly')
        OR
        ( DATEPART(DAY, [OffsetTime]) = DATEPART(DAY, @Date) AND @Mode='Daily')
        OR
        ( DATEPART(HOUR, [LogTime]) = @Hour AND  @Mode='Hourly' )

)

这里您需要传递一个名为@Mode 的额外参数,这样您就可以在存储过程中编写一个查询。

现在您可以像下面这样从您的 SP 拨打电话。

SELECT * FROM [dbo].[GetData](@Date, @Hour,'Hourly')

SELECT * FROM  [dbo].[GetData](@Date, NULL,'Yearly')

【讨论】:

  • 其实我只是从一张表中选择。最后,在Yearly() 函数中。 Hourly() 调用 Daily()Daily() 调用 Monthly()Monthly() 调用 Yearly()。这会改变您提议的功能吗?
  • 对不起,我误解了功能,我已经更新了答案,请检查。
  • 这行不通,恐怕。首先,AS Mode 语法无法解析,所以我不得不删除它。此外,该函数必须仅选择指定日期(例如 2018 年 10 月 15 日)内的行。 OR 关键字允许该日期之外的行进入结果集。
  • 现在每个类型的 where 子句明显不同,您可以针对这些人解决数据问题
  • 我觉得嵌套函数会使问题复杂化。您可以使用简单的 where 子句来实现这一点,其中每种类型的请求都用“OR”子句分隔。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多