首页 > 解决方案 > 查询以仅提取相关的列或具有特定 where 条件的数据

问题描述

我正在尝试编写一个 SQL 查询(最好不是存储过程)来提取具有与 where 条件相关的数据的特定列。

如图所示,如果我有一个where条件Report column = 'ABC',那么查询应该只返回列COL1 & COL4,因为它们只有报告 ABC 的数据。同样,如果它的Report='PQR'then 列COL2 & COL6

在现实生活中,我有大约 90 列。最好需要一个子查询或简单的 SQL 语句,而不是存储过程,因为我必须从 VB 应用程序调用它。

这是一个测试表

    create table report_test (
        report varchar(100),
        col1 int,
        col2 varchar(100),
        col3 int,
        col4 varchar(100),
        col5 varchar(100),
        col6 varchar(100)
    );
    insert into report_test (report, col1, col4) values ('abc', 1, '1');
    insert into report_test (report, col2, col6) values ('pqr', '1', '1');
    insert into report_test (report, col3) values ('xyz', 1);
    insert into report_test (report, col1, col4) values ('abc', 1, '1');
    insert into report_test (report, col2, col6) values ('pqr', '1', '1');
    insert into report_test (report, col3) values ('xyz', 1);

提前致谢。

在此处输入图像描述

标签: sqlsql-servertsqlnotnull

解决方案


这是一个存储过程,可以为您提供所需的内容。

表格示例

create table report_test (
    report varchar(100),
    col1 varchar(100),
    col2 varchar(100),
    col3 varchar(100),
    col4 varchar(100),
    col5 varchar(100),
    col6 varchar(100)
);
insert into report_test (report, col1, col4) values ('abc', '1', '1');
insert into report_test (report, col2, col6) values ('pqr', '1', '1');
insert into report_test (report, col3) values ('xyz', '1');

存储过程

评论是内联的。基本思想是这样的:

  • 查询元数据表 information_schema 报表表的所有列
  • 遍历每一列
  • 询问报告表给定报告的该列是否不为空
  • 如果不为空,则将其添加为要从中选择的列
  • 使用报告和选定的列(不为空)执行最终查询

现在,程序。

create procedure getReportInfo
    @report varchar(100)
as
begin

    -- holds name of the column as each column is checked
    declare @col nvarchar(100);

    -- holds 1 or 0 - 1 means column was not null for that report
    declare @cnt int;

    -- this is the SQL that asks DB whether a given column is not null in the database
    declare @colSQL nvarchar(max);

    -- holds parameter definition for dynamic queries
    declare @parameter_definition nvarchar(1000);

    -- this is the final SQL that will be executed
    declare @s nvarchar(1000);
    set @s = 'select report';

    declare c cursor read_only for
        select column_name from INFORMATION_SCHEMA.columns
        where table_name = 'report_test' and column_name <> 'report'
        order by ORDINAL_POSITION;

    open c;

    fetch next from c into @col;
    while @@FETCH_STATUS = 0
    begin

        -- ask DB whether column was not null in the table for a given report
        set @cnt = 0;
        set @colSQL = concat(
            'select @cnt_out = count(*) from report_test where report = @rep_temp and ',
            @col, ' is not null'
        );
        set @parameter_definition = N'@rep_temp nvarchar(100), @cnt_out int OUTPUT';
        execute sp_executesql @colSQL,
            @parameter_definition,
            @rep_temp = @report,
            @cnt_out = @cnt output;

        -- if column was not null, add it as a selectable field in the final query
        if @cnt > 0
        begin
            set @s = concat(@s, ', ', @col);
        end;

        fetch next from c into @col;
    end;

    close c;
    deallocate c;

    -- execute final query
    set @s = concat(@s, ' from report_test where report = @rep_temp');
    set @parameter_definition = N'@rep_temp nvarchar(100)';
    execute sp_executesql @s,
        @parameter_definition,
        @rep_temp = @report;

end
go

执行程序

execute getReportInfo 'pqr'
report  col2    col6
pqr       1      1


execute getReportInfo 'abc'
report  col1    col4
abc      1        1

execute getReportInfo 'xyz'
report  col3
xyz      1

这只是一个想法。根据报告表中的内容,您将不得不对其进行调整。这个例子中有几个概念:

  • 如何创建存储过程
  • 如何向其发送参数
  • 如何使用游标
  • 如何使用动态查询
  • 如何将参数发送到动态查询
  • 如何从动态查询中检索输出
  • 如何执行存储过程

从 VB 调用存储过程

请参阅这些文章:


推荐阅读