SQL中的宏概念
Posted
技术标签:
【中文标题】SQL中的宏概念【英文标题】:Macro concept in SQL 【发布时间】: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
【参考方案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');
【讨论】:
以上是关于SQL中的宏概念的主要内容,如果未能解决你的问题,请参考以下文章