如何显示将值和NULL列分别分组的“行”

时间:2019-04-10 13:58:19

标签: sql-server

有一个名为“ member”的表,该表有60列。只有一些列具有值; 5列具有值,其余55列为NULL

问题是带有值的列是分散的,我发现很难搜索该行以找到具有值的列。

我尝试了一些在发布此问题时收到的建议。下面是其中之一。

select * from table order by NULLIF(value,'') = '' DESC, value

我在下面尝试过

select * from member order by NULLIF(date_of_begin,'') 

当我想要这样的东西时,这不能满足我的要求。我使用一条select语句,并分隔所有具有要首先显示的值的列,然后分隔所有具有NULL的最后显示的列。

ID Member Name   Age      Gender       Date of begin    DOB     DOC     Extra
1   John         34         M          4/10/2019        NULL    NULL    NULL
2   Jack         NULL       M          4/11/2019        NULL    NULL    NULL
3   David        54         M          4/15/2019        NULL    NULL    NULL
4   Eric         NULL       M          4/16/2019        NULL    NULL    NULL
5   Ivan         45         M          4/10/2019        NULL    NULL    NULL

我想要一个select语句,它将上面的示例与以下分组分开。杰克的年龄为NULL,因此应将其放在最后一列并显示。这将使我的工作更容易找到哪些列为NULL以及哪些值进行了排序。

例如->

Select * from member where id =2 IS NOT NULL (I need help here in this statement change)

所需结果:

ID  Member Name       Gender       Date of begin    DOB     DOC     Extra  Age
2    Jack               M          4/11/2019        NULL    NULL    NULL   NULL

2 个答案:

答案 0 :(得分:0)

我建议的解决方案是在n行中存储一个记录

n是列数

然后,您可以使用排序依据来按需要对结果进行排序 或基于NULL值添加条件  我正在使用系统sql服务器表syscolumn和sysobjects

create table tab_mytable (id int ,colonne varchar(100),valeur varchar(100));
insert into tab_mytable(id,colonne) select c.colid,c.name from sysobjects o inner join 
syscolumns c on o.id=c.id where o.name='member' order by c.colid

declare @cmd as varchar(1000)
declare @mytab as table (val varchar(100))

declare mycursor  cursor for select colonne from tab_mytable
declare @colonne as varchar(100)
declare @val as varchar(100)
open mycursor
fetch mycursor into @colonne
while @@fetch_status=0
begin
set @cmd= 'select '+@colonne +' from member where id=2'
insert into @mytab exec(@cmd)
select @val=val from @mytab
set @cmd='update tab_mytable set valeur='''+@val+''' where colonne='''+@colonne+''''
exec(@cmd)
print @cmd
delete from @mytab
fetch mycursor into @colonne
end
close mycursor
deallocate mycursor
--Put here your Query to display teh results as you wish
select * from tab_mytable order by valeur

您也可以使用UNPIVOT statement

但是在这种情况下,您必须编写所有列名,对于上述解决方案,您将不会在脚本中编写它们。

答案 1 :(得分:0)

我不愿发誓这样做值得,但是如果您一次只需要一个ID,或者至少只需要几个,那么这将仅返回非null列值。如果您想承受更大的痛苦,并尝试将其旋转回排,请尝试一下,但这会为您提供可行的结果集。

我们正在使用CROSS APPLY取消显示结果,然后处置NULL值。您的数据看起来不再像是行了,但是您需要的少量数据点就在那里。

为了使用CROSS APPLY,为了将所有列值都集中到一个列中,我CAST将它们全部作为NVARCHAR数据,所以结果是所有文本字段。 / p>

在该示例中,我返回了两个ID值,以便您可以看到它的外观。

数据设置,以防其他任何人摆动:

DECLARE @table TABLE(
   ID            INTEGER  NOT NULL PRIMARY KEY 
  ,Member_Name   VARCHAR(5) NULL
  ,Age           INTEGER NULL
  ,Gender        VARCHAR(1) NULL
  ,Date_of_begin DATE  NOT NULL
  ,DOB           VARCHAR(4) NULL
  ,DOC           VARCHAR(4) NULL
  ,Extra         VARCHAR(4) NULL
);
INSERT INTO @table(ID,Member_Name,Age,Gender,Date_of_begin,DOB,DOC,Extra) VALUES (1,'John',34,'M','4/10/2019',NULL,NULL,NULL);
INSERT INTO @table(ID,Member_Name,Age,Gender,Date_of_begin,DOB,DOC,Extra) VALUES (2,'Jack',NULL,'M','4/11/2019',NULL,NULL,NULL);
INSERT INTO @table(ID,Member_Name,Age,Gender,Date_of_begin,DOB,DOC,Extra) VALUES (3,'David',54,'M','4/15/2019',NULL,NULL,NULL);
INSERT INTO @table(ID,Member_Name,Age,Gender,Date_of_begin,DOB,DOC,Extra) VALUES (4,'Eric',NULL,'M','4/16/2019',NULL,NULL,NULL);
INSERT INTO @table(ID,Member_Name,Age,Gender,Date_of_begin,DOB,DOC,Extra) VALUES (5,'Ivan',45,'M','4/10/2019',NULL,NULL,NULL);

这是查询。

SELECT 
  c.*
FROM @table AS t
CROSS APPLY (VALUES ('ID',CAST(t.ID AS NVARCHAR(30))),
                    ('Member_Name',CAST(t.Member_Name AS NVARCHAR(30))),
                    ('Age',CAST(t.Age AS NVARCHAR(30))),
                    ('Gender',CAST(t.Gender AS NVARCHAR(30))),
                    ('Date_of_begin',CAST(t.Date_of_begin AS NVARCHAR(30))),
                    ('DOB',CAST(t.DOB AS NVARCHAR(30))),
                    ('DOC',CAST(t.DOC AS NVARCHAR(30))),
                    ('Extra',CAST(t.Extra AS NVARCHAR(30)))
            ) c (ColName,ColValue)
WHERE t.ID IN (2,3)
AND c.ColValue IS NOT NULL
ORDER BY 
  t.ID,
  CASE
    WHEN c.ColName = 'ID' THEN 1
    WHEN c.ColName = 'Member_Name' THEN 2
    ELSE 3
  END 

结果:

+---------------+------------+
|    ColName    |  ColValue  |
+---------------+------------+
| ID            | 2          |
| Member_Name   | Jack       |
| Gender        | M          |
| Date_of_begin | 2019-04-11 |
| ID            | 3          |
| Member_Name   | David      |
| Age           | 54         |
| Gender        | M          |
| Date_of_begin | 2019-04-15 |
+---------------+------------+