#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. Привет, спасибо за это, на самом деле я не могу или не могу создать какую-либо таблицу. Единственное, что мне разрешено, это запрашивать. Спасибо