Как отобразить «строки», в которых столбцы value и NULL сгруппированы отдельно

#sql-server

#sql-сервер

Вопрос:

Существует таблица с именем «член», в которой 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, который разделит приведенный выше пример с приведенной ниже группировкой. Возраст равен НУЛЮ для Jack, поэтому его следует поместить в последний столбец и отобразить. Это облегчит мою работу по поиску того, какие столбцы имеют значение 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

  

Комментарии:

1. Можете ли вы включить больший набор данных, который лучше объясняет, что вы пытаетесь здесь сделать?

2. Я пытался выровнять ваши данные, но, похоже, что-то не так.

3. Я действительно хочу, чтобы это имело смысл, но это просто не так. Объяснение и данные просто не совпадают вообще.

4. Я думаю, вы просите отсортировать столбцы слева направо на основе тех, которые имеют ненулевые значения, идущие первыми, затем те, у которых нулевые значения идут последними, правильно?

5. @ChrisHackett, это именно то, что я хочу.

Ответ №1:

Я не готов поклясться, что это стоит усилий, но если вам нужно только ID по одному или, по крайней мере, только несколько, это вернет только ненулевые значения столбцов. Если вы хотите испытать еще большую боль и попытаться преобразовать ее обратно в строки, сделайте это, но это даст вам работоспособный набор результатов.

Мы используем CROSS APPLY для открепления ваших результатов, а затем удаления NULL значений. Ваши данные больше не выглядят как строка, но несколько точек данных, которые вам нужны, есть для вас.

Используя CROSS APPLY , чтобы собрать все значения столбцов в один столбец, я CAST использую их все как NVARCHAR данные, поэтому все ваши результаты представляют собой текстовые поля.

В примере я вернул два 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 |
 --------------- ------------ 
  

Комментарии:

1. Пользователь Jake попросил найти значения Null для таблицы с 65 столбцами, решение, которое вы даете, предназначено для меньшего числа, пожалуйста, взгляните на предоставленное мной решение, которое может работать для любого количества столбцов

2. @KemalALGAZZAH, решение, которое я написал, предназначалось для предоставленных примеров данных и просто для того, чтобы показать один метод для выполнения поставленной задачи. Очевидно, что код необходимо будет переписать для производственной системы OP. Кажется, что ваше решение тоже будет работать.

Ответ №2:

Решение, которое я предлагаю, — сохранить одну запись в n строках,

n — количество столбцов,

затем вы можете упорядочить результат по своему усмотрению, используя order by или добавить критерии на основе значений NULL Я использую системные таблицы sql server syscolumn s и 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

Но при этом использовании вам нужно записать все имена столбцов, для решения, приведенного выше, вы не будете записывать их в свой скрипт

Комментарии:

1. Привет, спасибо за это, на самом деле я не могу или не могу создать какую-либо таблицу. Единственное, что мне разрешено, это запрашивать. Спасибо