SQL - 如何在相关表中每行获得 1 个空列?

Posted

技术标签:

【中文标题】SQL - 如何在相关表中每行获得 1 个空列?【英文标题】:SQL - How do I get 1 empty column per row in a related table? 【发布时间】:2021-06-11 10:03:26 【问题描述】:

我正在尝试编写一个 SQL 查询,该查询根据 Crystal Report 的相关表 (t1) 中的行数添加一定数量的空列。这些列应该有数据集名称的标题。

所以它应该看起来像这样:

但是,每次添加新行时,我都需要更改脚本(例如,开店 - 不经常,但确实会发生)。

我考虑过使用数据透视函数,但我认为必须定义行数 - 另外,不会发生计算/聚合。

有人知道如何解决这个问题吗?

【问题讨论】:

样本数据和预期结果将帮助我们帮助您。然而,最肯定的是,您将需要动态 SQL,那么这真的是您想要走的路吗? 静态地,我会这样写:with a as ([select sql statement here]), b as (select top 0 null as [MS 2], null as [MS 1], null as [MS 3], null as [MS 5], null as [MS 4] from xtrade.KUNDE ) select * from a cross join b 预期结果应该类似于帖子中的表格。但是我尝试编写一个动态语句,得到与 cte b 相同的结果 - 感谢您的建议,直到这里 Crystal Reports 可以交叉表,最好让 CR 来做这件事,而不是 DB。数据库查询不应该有不同数量的列(行数不同,列数没有)。这感觉很像“前端的问题,而不是后端的问题” 如果Crystal 能够做到这一点,那就更好了,我正在深入研究。感谢您的输入 Crosstab 在那个例子中并不适合我。但是我可以使用动态 SQL 来实现结果。我在下面发布 SQL。谢谢 【参考方案1】:

正如 Larnu 已经提到的,动态 SQL 将是一种方法。我建议结合使用 XML PATH 和动态 SQL。举个例子:

DECLARE @colList VARCHAR(MAX) = (SELECT STUFF((SELECT ',NULL as t1_row' + cast(col1 AS varchar(3))
                                   FROM MyTable
                                   FOR XML PATH('')) ,1,1,'') AS Txt
                                )

DECLARE @stmt VARCHAR(MAX) = 'SELECT Col1, Col2, Col3, ' + @colList + ' FROM MyTable'

EXEC (@stmt)

【讨论】:

【参考方案2】:

我能够使用动态 SQL 实现结果。 脚本看起来像这样:

DECLARE @STRSQL NVARCHAR(MAX) = 'WITH a AS (SELECT ';
DECLARE @Kst nvarchar(6);
DECLARE @Markt NVARCHAR(30);
DECLARE @SCHEMA_NAME VARCHAR(50) = 'XTRADE';


DECLARE C1 CURSOR FOR 
    SELECT NUMMER, BEZEICHNUNG 
    from XTRADE.KUNDE 
    where NUMMER > 99 and NUMMER not in (194, 196, 198) 
            and (DATUM_SCHLIESSUNG > GETDATE() or DATUM_SCHLIESSUNG is null)
    order by    BEZEICHNUNG


    OPEN C1

            PRINT @Kst + ' ' + @Markt
            FETCH NEXT
            FROM C1 into @Kst, @Markt       
    
        while @@FETCH_STATUS = 0

        BEGIN
            SET @STRSQL = @STRSQL + 'null as [' + @Markt + '], '
            FETCH NEXT
            FROM C1 into @Kst, @Markt
        END


    CLOSE C1

DEALLOCATE C1;

SET @STRSQL = left(@STRSQL, len(@Strsql) - 1) + ')'

DECLARE @Statement nvarchar(max) = ', b as (select 1 as Col1, 1 as Col2, 5 as Col3 union all select 2,2,12 union all select 3, 3, 42)';
DECLARE @Exec nvarchar(max) = @STRSQL + @Statement + 'select * from b cross join a';

print @Exec;
exec sp_executesql @Exec

【讨论】:

以上是关于SQL - 如何在相关表中每行获得 1 个空列?的主要内容,如果未能解决你的问题,请参考以下文章

选择 PL/SQL 中两个非空列值之间的行集

把 Excel 文件导入 SQL Server 中出现大量的空列 如何不出现空列呢,或怎么迅速删除

如何使用 MYSQL 中的连接从多个表中获取多个列并在非空列上显示数据以及在空列上显示 null 或零

如何编写/优化需要从 6 个相关表中选择数据的 sql 查询,直到获得所需的数据

如何从oracle中的另一个表中填充空列?

oracle如何向空表中添加一个类型为clob的非空列