是否有一种在投影级别应用条件的简单方法?我的意思是在一系列字段(列)中,我们如何只选择那些具有特定条件的字段?
示例:的
假设我们有一个查询结果如下:
Id Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8 Col9 Col10 Col11
- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
1 V1_1 NULL NULL V4_1 NULL NULL NULL NULL NULL V10_1 NULL
2 V1_2 NULL NULL NULL NULL NULL NULL NULL NULL V10_2 NULL
3 V1_3 NULL NULL V4_3 NULL NULL NULL NULL NULL V10_3 NULL
我们如何 select only the fields which contains none null values while we don't know which of them contains none null values
?结果就是这样:
Id Col1 Col4 Col10
- ---- ---- ----
1 V1_1 V4_1 V10_1
2 V1_2 NULL V10_2
3 V1_3 V4_3 V10_3
通常我会使用硬编码执行此类查询,我可以在sys.all_obejcts
和sys.all_columns
,MsSQL Server
等{{1}中查询all_tab_cols
,all_tables
}}。并且不使用任何内容,一个或多个Oracle
s,cursor
语句,case
,多个pivot
或if
。
:对于T-SQL中包含上述数据的表,我可以这样做:
dynamic sql
但正如你所看到的那样,这个想法根本不常见,对这些场景做这样的编码有点困难
您是否知道这种查询的简单方法或模式?
RDBMS并不重要,对任何RDBMS来说都是一个很好的解决方案非常有用。
我希望答案一般不仅仅是我提到的例子。
答案 0 :(得分:0)
这是一个T-SQL解决方案。您所要做的就是将@TargetTable更改为您想要的表格。希望这可以帮助!我评论了我的代码解释了所有内容,但如果您有任何问题,请告诉我们!
IF OBJECT_ID('myTable') IS NOT NULL
DROP TABLE dbo.myTable;
CREATE TABLE myTable
(
ID INT IDENTITY(1,1),
Col1 VARCHAR(25),
Col2 VARCHAR(25),
Col3 VARCHAR(25)
)
INSERT INTO dbo.myTable(Col1,Col2,Col3)
VALUES ('v1_1',NULL,NULL),
('v1_2','v2_2',NULL),
('v1_3',NULL,NULL);
/* Now that I've set up the problem, here's for the actual code*/
--Set your desired table
DECLARE @TargetTable VARCHAR(100) = 'myTable'
--If this global temp table exists, drop it
IF OBJECT_ID('##tempTable') IS NOT NULL
EXEC('DROP TABLE ##tempTable');
--This is going to take one character and cast it to NCHAR(1)
--If there are no characters, it will simply return NULL
DECLARE @AllColumns VARCHAR(MAX);
SELECT @AllColumns = COALESCE(@AllColumns + ',','') + 'CAST(LEFT(' + QUOTENAME(COLUMN_NAME) + ',1) AS NCHAR(1)) AS ' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE TABLE_NAME = @TargetTable
/*Load your char results into a global temp table*/
EXEC('SELECT ' + @AllColumns + ' INTO ##tempTable FROM ' + @TargetTable);
/*Here's where the fun beings*/
/* @DesiredCol holds the name of columns that are not null.
UNPIVOT the data.
Where clause gets rid of columns with only NULL values.
Group by only allows distinct columns.
You the select from your ORIGINAL table, not my funky nchar(1) global temp table.
*/
EXEC(
'DECLARE @DesiredCol VARCHAR(MAX);
SELECT @DesiredCol = COALESCE(@DesiredCol + '','','''') + QUOTENAME(col)
FROM ##temptable
UNPIVOT
(
val FOR col IN ([ID],[Col1],[Col2],[Col3])
) pvt
WHERE pvt.val IS NOT NULL
GROUP BY col
EXEC (''SELECT '' + @DesiredCol + '' FROM ##' + @TargetTable + ''')'
)
--Cleanup
IF OBJECT_ID('##tempTable') IS NOT NULL
EXEC('DROP TABLE ##tempTable');