首页 > 解决方案 > 列数取决于变量

问题描述

我有一个带有数据的 sql 表

日期 票号 成本
01.08.2021 ui1234 15

我需要输出

出票日期、10 美元之前的票数、20 美元之前的票数、30 美元之前的票数等。

列数可能因变量中的指定值而异

例如,如果您在变量 500 中指定成本,那么将有 50 列,渐变不会改变

标签: sqldynamic-columns

解决方案


您可以使用动态 SQL 执行此操作。我将展示一种使用 SQL Server 的技术,但您可以适应另一个 RDBMS。这是存储过程的绝佳候选者,但我将向您展示一个脚本。我将创建一个临时表并用示例数据填充它。那时,我们将构建一个动态 SQL 查询,然后当它准备好时,我们可以让 SQL Server 为我们执行它。在这个脚本中我是 SQL 语句,所以你可以看到它,如果提供的不大于零SELECT,我会显示一个错误。@Cost

DROP TABLE IF EXISTS #Tickets;
CREATE TABLE #Tickets(
    [date] DATE NOT NULL, 
    [ticket_id] VARCHAR(10) NOT NULL, 
    [cost] DECIMAL(5,2) NOT NULL
);
INSERT INTO #Tickets([date],[ticket_id],[cost])
VALUES ('8-1-2021','ui123', 15.00), ('8-1-2021','ui456', 25.00);


-- this is the parameter you would accept - the maximum cost for the columns
DECLARE @Cost DECIMAL(5,2);
SELECT @Cost = 50.00;
DECLARE @Sql NVARCHAR(max);
SELECT @Sql = N'SELECT ';
-- we will step by 10 until we reach the @Cost
DECLARE @Step INT;
SELECT @Step = 10;

IF (@Cost <= 0) 
BEGIN
    SELECT 'Cost must be positive';
    RETURN;
END

WHILE (@Step <= @Cost)
BEGIN
    IF @Step > 10 SELECT @Sql = CONCAT(@Sql, N', ');
    SELECT @Sql = CONCAT(@Sql, N' COUNT(CASE WHEN cost BETWEEN ', @Step - 10, N' AND ', @Step, N' THEN 1 ELSE NULL END) AS [', @Step, N']');
    SELECT @Step = @Step + 10;
END

SELECT @Sql = CONCAT(@Sql, N' FROM #Tickets');
-- show the statement
SELECT @Sql;
-- run the statement
EXECUTE sp_executesql @Sql;

推荐阅读