【问题标题】:Macro concept in SQLSQL中的宏概念
【发布时间】:2021-12-29 00:59:47
【问题描述】:

是否有任何数据库引擎具有类 C 宏的概念?这是一个我想让它更具可读性的示例:

SELECT
  SUM(Profit) AS Total,
  (SELECT AVG(Profit) FROM This 
     WHERE Category=This.Category AND Product=This.Product
     AND     PARSE_DATE('%M %d%, Y', CONCAT(This.Month ' 1, ' This.Year))
     BETWEEN PARSE_DATE('%M %d%, Y', CONCAT(This.Month ' 1, ' This.Year))
     AND PARSE_DATE('%M %d%, Y', CONCAT(This.Month ' 1, ' This.Year))-INTERVAL 3 MONTH
FROM Tbl

我宁愿有这样的东西:

#define dt PARSE_DATE('%M %d%, Y', CONCAT(This.Month ' 1, ' This.Year))

SELECT
  SUM(Profit) AS Total,
  (SELECT AVG(Profit) FROM This
     WHERE Category=This.Category AND Product=This.Product
     AND dt BETWEEN dt AND (dt-INTERVAL 3 MONTH)
FROM Tbl

在主要的 DBMS 中是否存在或常用类似的东西?

【问题讨论】:

  • 作为宏 - 没有。用户自定义函数...
  • 每个 SQL 方言都支持CREATE FUNCTION DDL 语句 - 调查一下。
  • SQL中没有宏的概念。此外,没有任何 SQL 代码预处理。最相似的似乎是存储对象或动态 SQL。
  • 如果您觉得您正在寻找交叉申请。如果您提供一个小数据样本和所需的结果,也许它会有助于可视化
  • @JohnCappelletti 请注意 cross apply 是非标准 SQL,ANSI SQL 中的等价物将是 cross join lateral

标签: mysql sql sql-server postgresql oracle


【解决方案1】:

从 Oracle 12 开始,您可以在子查询分解 (WITH) 子句中声明一个函数:

WITH FUNCTION dt (month INT, year INT) RETURN DATE AS
BEGIN
  RETURN TO_DATE(year || '-' || month || '-01', 'YYYY-MM-DD');
END;
SELECT *
FROM   this
WHERE  dt(this.month, this.year)
         BETWEEN ADD_MONTHS(dt(this.month, this.year), -3)
         AND     dt(this.month, this.year);

db小提琴here


从Oracle 21,你可以写SQL macros

CREATE FUNCTION dt (month INT, year INT)
RETURN VARCHAR2 SQL_MACRO(SCALAR)
AS
BEGIN
  RETURN 'TO_DATE(year || ''-'' || month || ''-01'', ''YYYY-MM-DD'')';
END;
/

然后将其用作:

SELECT *
FROM   this
WHERE  dt(this.month, this.year)
         BETWEEN ADD_MONTHS(dt(this.month, this.year), -3)
         AND     dt(this.month, this.year);

查询将被重写为:

SELECT *
FROM   this
WHERE  TO_DATE(this.year || '-' || this.month || '-01', 'YYYY-MM-DD')
         BETWEEN ADD_MONTHS(TO_DATE(this.year || '-' || this.month || '-01', 'YYYY-MM-DD'), -3)
         AND     TO_DATE(this.year || '-' || this.month || '-01', 'YYYY-MM-DD');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多