SQL. Фильтровать нулевые поля в резонансе - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть пользователи таблицы с полями: id, имя, возраст, пол, страна, город, комментарий. Поля могут быть нулевыми. Например:

cursor.execute('select * from users where id = 12')
cursor.fetchone()
(12, 'alex', 33, 'male', None, None, None)

Как я могу получить обратно из запроса только не пустые поля?

Этот запрос должен вернуть мне только

(12, 'alex', 33, 'male')

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

1 Ответ

0 голосов
/ 07 апреля 2020

Итак, вам нужно получить индивидуальный таблично-ориентированный результат со столбцами, динамически генерируемыми с помощью SQL ANSI. Вам потребуется комплект с двумя процедурами:

  1. Проверьте, столбец имеет только значения NULL или нет.
  2. Соберите все столбцы с значениями NO NULL.

С помощью этих двух процедур вы можете проверить каждый столбец таблицы strcuture и получить вывод без столбцы со значениями NULL.

Первая процедура является обобщенной c:

set delimiter //

create procedure check_field_null(col varchar(64), 
                                  schemaname varchar(255),
                                  tablename varchar(255), 
                                  out QN int)
BEGIN
   SET @sSQL = concat('SELECT  @N := COUNT(*) FROM ', schemaname, '.', tablename , ' WHERE (', col, ' <=> NULL);');
   prepare stm from @sSQL;
   execute stm;
   set QN =@N;
   deallocate prepare stm;

END
//

Вторая процедура означает, что у вас есть вышеупомянутый метод для определения столбцов NOT NULLS и помещения всех в поиск .

set delimiter //
create procedure cur_cs_customer(inout allcols varchar(255), in my_schema_name varchar(64), in my_table_name varchar(64))
BEGIN
 DECLARE Count_Null  int default 0;
 DECLARE initial INT DEFAULT 0;
 DECLARE MYCOL   char(64);
 DECLARE ch_done INT DEFAULT 0;
 DECLARE cs_cur1 CURSOR 
         FOR SELECT C.COLUMN_NAME
             FROM information_schema.COLUMNS C
             WHERE C.TABLE_SCHEMA = my_schema_name
               AND C.TABLE_NAME = my_table_name;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET ch_done = true;

open cs_cur1;

read_cs_cur1:
LOOP
    FETCH cs_cur1 INTO MYCOL;

    IF (ch_done ) THEN
        LEAVE read_cs_cur1;
    END IF;

    IF NOT isnull(MYCOL) THEN

        call check_field_null(MYCOL, 
                              my_schema_name, 
                              my_table_name,
                              Count_Null);

        if Count_Null = 0 then
            /* Only it inlcudes fields with not null values */
            set initial = initial + 1;

            if initial = 1 then
                SET allcols =  MYCOL;
            else                
                SET allcols  = concat( cast(allcols as char(255)), ',', MYCOL);
            end if;
        end if;
    END IF;

END LOOP read_cs_cur1;

close cs_cur1;

select allcols;
END
//

После этого вы можете выполнить следующее:

set delimiter ; 
call cur_cs_customer(@my_args, 'schema_name', 'users'); 
select @my_args; 
set @stm = concat('SELECT ', @my_args, ' FROM users;'); 
PREPARE stmt1 FROM @stm; 
execute stmt1; 
deallocate prepare stmt1;

Дальнейшее объяснение можно проверить в статье здесь ! .

Надеюсь, этот совет поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...