You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于表名与日期列清单实现各表日期维度行统计的DRY方案?

多表按日期维度统计总行数与X列非空行数的DRY实现方案

问题背景

需要对一组数据表按日期维度统计每张表的总行数,以及X列的非空行数,但每张表的日期列名称各不相同。

常规的重复式实现(不符合DRY原则):

SELECT 'TableA' AS 'TableName', [AsOfDate], COUNT(*) AS 'Rowcount', SUM(IIF([X] IS NULL,0,1)) AS 'NonEmpty'
FROM TableA GROUP BY [AsOfDate]
UNION ALL
SELECT 'TableB' AS 'TableName', [Snapshot Date], COUNT(*) AS 'Rowcount', SUM(IIF([X] IS NULL,0,1)) AS 'NonEmpty'
FROM TableB GROUP BY [Snapshot Date]
-- ... 重复添加UNION ALL处理TableC、D、E等表

期望基于包含表名与对应日期列的清单表实现,避免重复代码,示例思路如下:

WITH Tables AS ( 
    SELECT * FROM ( VALUES
        ('TableA', 'AsOfDate'),
        ('TableB', 'Snapshot Date'),
        -- ...
        ('TableZ', 'Date of Record')
    ) AS Tables([Table],[DateColumn]) 
)
SELECT MyFn([Table],[DateColumn]) FROM Tables

预期输出格式:

[Table]    [Date]    [Rows]    [NonEmpty]
TableA     2022-01-01    20    18
TableA     2022-01-02    20    19
TableA     2022-01-03    20     0
TableB     2022-01-01    30    28
-- ...

原本计划用接收表名和列名的函数执行动态SQL,但该方法不可行,现提供符合DRY原则的解决方案。

解决方案

方法1:基于清单表生成动态SQL

利用清单表自动拼接所有表的统计语句,一次性执行,无需手动重复编写:

DECLARE @SQL NVARCHAR(MAX) = ''

SELECT @SQL = @SQL + 
    'SELECT ''' + [Table] + ''' AS [TableName], [' + [DateColumn] + '] AS [Date], COUNT(*) AS [Rows], SUM(IIF([X] IS NULL, 0, 1)) AS [NonEmpty]
     FROM [' + [Table] + '] GROUP BY [' + [DateColumn] + ']
     UNION ALL '
FROM (
    VALUES
        ('TableA', 'AsOfDate'),
        ('TableB', 'Snapshot Date'),
        ('TableZ', 'Date of Record')
) AS Tables([Table],[DateColumn])

-- 移除末尾多余的UNION ALL
SET @SQL = LEFT(@SQL, LEN(@SQL) - 10)

-- 执行生成的统计语句
EXEC sp_executesql @SQL

方法2:结合系统视图自动化生成(适用于SQL Server)

如果目标表集中在特定Schema下,可通过系统视图自动匹配表和日期列,进一步减少维护成本:

DECLARE @SQL NVARCHAR(MAX) = ''

SELECT @SQL = @SQL + 
    'SELECT ''' + t.name + ''' AS [TableName], [' + c.name + '] AS [Date], COUNT(*) AS [Rows], SUM(IIF([X] IS NULL, 0, 1)) AS [NonEmpty]
     FROM dbo.[' + t.name + '] GROUP BY [' + c.name + ']
     UNION ALL '
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
WHERE t.schema_id = SCHEMA_ID('dbo')
    AND t.name IN ('TableA', 'TableB', 'TableZ') -- 指定目标表
    AND c.name IN ('AsOfDate', 'Snapshot Date', 'Date of Record') -- 对应日期列

SET @SQL = LEFT(@SQL, LEN(@SQL) - 10)
EXEC sp_executesql @SQL

说明

  • 两种方法均符合DRY原则,后续新增表只需修改清单表或系统视图的筛选条件即可,无需重复编写统计逻辑。
  • 若表名或日期列包含特殊字符,需额外处理转义,确保SQL语句的合法性。

内容的提问来源于stack exchange,提问作者alazyworkaholic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 08:54:17