sql - 查询以仅提取相关的列或具有特定 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);
提前致谢。
解决方案
这是一个存储过程,可以为您提供所需的内容。
表格示例
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 调用存储过程
请参阅这些文章:
推荐阅读
- angular - 为什么我不能得到身体形式 Angular
- owl - 使用 OWL API 将类子层次结构合并到另一个本体
- python - 在条件下在数据框中添加一行
- java - 如何在读取 csv 文件时跳过重复的行?
- spring - Spring WebClient Hystrix 或 Resilience4j 还是什么都没有?
- wordpress - 如何使 WordPress Bootstrap 父菜单在桌面上可点击而在移动视图中不可点击?
- webpack - 生产 webpack 构建中的“未捕获的 ReferenceError:未定义导出”
- javascript - 从 html 调用模态
- python - while liste[i] != " ": 是列表索引问题
- excel - IF 配方,90 天内状态