选择值为NULL的列名

时间:2016-06-26 06:54:23

标签: sql sql-server tsql null

好的,4个小时的编码,只有6个小时的搜索......而且我开始时没有比这更好的了。这是我的问题。我有一个表(tmpShell),它有12列。它是一个没有约束的基本表 - 用于临时报告。当我们插入数据时,我必须提取一个ID号(PatientId)和所有列NAMES,其中该PatientId的值为null。

示例:

PatientId    Fname    Lname      DOB 
123455       Sam      NULL       NULL
2345455      NULL     Doe        1/1/1980
09172349     John     Jone       NULL

我想要回归的是:

PatientId    ErrorMsg
123455       Lname,DOB
2345455      Fname
09172349     DOB

当然,如果所有列都有值,则errormsg将为null。

我已尝试并失败了大约300个不同的代码,但这似乎是我能得到的最接近的代码。不幸的是,这只返回每一列,而不是空值。     

     ALTER PROC [sp_aaShowAllNullColumns]
      @tableName VARCHAR(255)
     AS
      BEGIN
            SET NOCOUNT ON;

DECLARE @sql NVARCHAR(4000); DECLARE @cols NVARCHAR(4000); DECLARE @tcols TABLE ( [colbit] NVARCHAR(255) ); --DECLARE @tablename VARCHAR(255) = 'tmpShell'; INSERT @tcols SELECT 'count(' + [columns].[name] + ') as ' + [columns].[name] + ', ' AS [colbit] FROM [sys].[columns] WHERE [columns].[object_id] = OBJECT_ID(@tableName); SELECT @cols = COALESCE(@cols, ', ', '') + [@tcols].[colbit] FROM @tcols; SELECT @cols = SUBSTRING(@cols, 1, ( LEN(@cols) - 1 )); SELECT @cols = ISNULL(@cols, ''); SELECT @sql = 'select patientid, count(*) as Rows' + @cols + ' from ' + @tableName + ' group by patientid having count(*) > 0'; CREATE TABLE [tmpShell2] ( [patientid] VARCHAR(15) ,[Rows] CHAR(2) ,[Rn] CHAR(2) ,[patId] CHAR(2) ,[fname] CHAR(2) ,[lname] CHAR(2) ,[dob] CHAR(2) ,[addr1] CHAR(2) ,[city] CHAR(2) ,[state] CHAR(2) ,[zip] CHAR(2) ,[country] CHAR(2) ,[psite] CHAR(2) ,[csite] CHAR(2) ,[ssite] CHAR(2) ,[scode] CHAR(2) ,[sfid] CHAR(2) ,[taskid] CHAR(2) ,[errormsg] CHAR(2) ); INSERT INTO [tmpShell2] EXEC [sys].[sp_executesql] @sql; DECLARE @tbl VARCHAR(255) = 'tmpShell2'; SELECT DISTINCT [TS].[patientid] , STUFF(( SELECT DISTINCT ', ' + [C].[name] FROM [tmpShell2] AS [TS2] JOIN [sys].[columns] AS [C] ON [C].[object_id] = OBJECT_ID(@tbl) WHERE [C].[name] NOT IN ( 'SFID', 'TaskId', 'ErrorMsg' ) AND [C].[name] IS NOT NULL FOR XML PATH('') ), 1, 1, '') FROM [tmpShell2] AS [TS]; DROP TABLE [dbo].[tmpShell2]; END; GO EXEC [sp_aaShowAllNullColumns] 'tmpShell'; </pre>

5 个答案:

答案 0 :(得分:8)

我认为你复杂的事情。

您可以尝试使用 public static void main(String[] args) { // The name of the file to open. String fileName = "file.txt"; int counter = 0; // This will reference one line at a time String line = null; FileReader fileReader = null; int chars = 0; int max = 55; try { // FileReader reads text files in the default encoding. fileReader = new FileReader(fileName); // Always wrap FileReader in BufferedReader. BufferedReader bufferedReader = new BufferedReader(fileReader); while ((line = bufferedReader.readLine()) != null) { counter++; if (counter == 1) { chars += line.length(); System.out.println(chars); System.out.println(line); if (chars == max) { //if max characters reached jump to the 7th line counter += 6; } System.out.println(counter); } } } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } }

CASE EXPRESSION

这将导致SELECT t.patientID, CASE WHEN t.fname is NULL THEN 'Fname,' ELSE '' END + CASE WHEN t.Lname is NULL THEN 'Lname,' ELSE '' END + CASE WHEN t.DOB is NULL THEN 'DOB,' ELSE '' END ..... as ErrorMsg FROM YourTable t 末尾有一个不必要的逗号,为了处理它你可以这样做:

errorMsg

这将使最后一个逗号唯一,因为它将有一个与其连接的空格,并确保它只会被删除。

答案 1 :(得分:3)

这样的事情怎么样?

SELECT
a.PatientID
, CASE a.tmpCol
    WHEN '' THEN NULL
    ELSE STUFF(a.tmpCol,1,1,'')
END AS ErrorMsg
FROM
(
SELECT
    PatientID
    , CASE WHEN FirstName IS NULL THEN ',FirstName' ELSE '' END
    + CASE WHEN LastName IS NULL THEN ',LastName' ELSE '' END
    + CASE WHEN DOB IS NULL THEN ',DOB' ELSE '' END AS tmpCol
FROM
    <tableName>
) a;

答案 2 :(得分:2)

您可以使用数据透视查询来获得所需的结果。以下查询应该近似于您想要的输出:

SELECT PatientId,
    CONCAT(CASE WHEN Fname IS NULL THEN 'Fname ' ELSE '' END,
           CASE WHEN Lname IS NULL THEN 'Lname ' ELSE '' END,
           CASE WHEN DOB IS NULL THEN 'DOB' ELSE '' END)
FROM yourTable

答案 3 :(得分:1)

这是一个基于https://stackoverflow.com/a/38036046/2314737的SQLfiddle,处理逗号

http://sqlfiddle.com/#!9/708796/1

SELECT PatientId,
    REPLACE(RTRIM(CONCAT(CASE WHEN Fname IS NULL THEN 'Fname ' ELSE '' END,
           CASE WHEN Lname IS NULL THEN 'Lname ' ELSE '' END,
           CASE WHEN DOB IS NULL THEN 'DOB' ELSE '' END)),
            ' ',',')
FROM YourTable

答案 4 :(得分:0)

这是一个存储过程,它将接受模式名称,表名和列名,然后生成所需的结果。

ALTER PROCEDURE [dbo].[DynamicErrorProducing]
@schema_name NVARCHAR(100),
@table_name  NVARCHAR(100),
@column_name NVARCHAR(100)
AS
BEGIN
DECLARE @countTable  TINYINT;
DECLARE @countColumn TINYINT;
DECLARE @string NVARCHAR(MAX);
DECLARE @sqlString NVARCHAR(MAX);

SET @countTable=0;

SELECT
    @countTable=COUNT(*)
FROM
    sys.tables
WHERE
    SCHEMA_NAME(schema_id)=@schema_name
    AND name=@table_name;

-- If there is no table as described, quit with an error
IF (@countTable = 0)
    RETURN 0;

SET @countColumn=0;

SELECT
    @countColumn=COUNT(*)
FROM
    sys.columns
WHERE
    object_id = OBJECT_ID(@schema_name+'.'+@table_name)
    AND name=@column_name;

IF (@countColumn<> 1)
    RETURN;

SELECT
    @countColumn=COUNT(*)
FROM
    sys.columns
WHERE
    object_id = OBJECT_ID(@schema_name+'.'+@table_name)
    AND name<>@column_name;

IF (@countColumn<1)
    RETURN;

SELECT @string=STUFF(
    (
    SELECT
        '+ CASE WHEN '+name+' IS NULL THEN '''' ELSE '','+name+''' END '
    FROM
        sys.columns
    WHERE
        object_id = OBJECT_ID(@schema_name+'.'+@table_name)
        AND name<>@column_name
    FOR XML PATH(''))
    ,1,2,'');


SET @sqlString=N'
SELECT
    a.'+@column_name+'
    , CASE WHEN a.tmpCol='''' THEN NULL ELSE STUFF(a.tmpCol,1,1,'''') END AS ErrMsg
FROM
(
SELECT
    '+@column_name+'
    ,'+@string+' AS tmpCol
FROM
    '+@schema_name+'.'+@table_name+'
) a';

EXEC sp_executesql
    @statement=@sqlString;

END


GO