有一个名为“ 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
答案 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 |
+---------------+------------+