Необходим Очень необычный запрос MySQL

Тема в разделе "Базы данных", создана пользователем QuZ, 8 ноя 2017.

Модераторы: latteo
  1. QuZ

    QuZ Постоялец

    Регистр.:
    18 июл 2009
    Сообщения:
    84
    Симпатии:
    49
    Добрый вечер. Мне необходим запрос следующего рода. Готов отблагодарить за него.

    Необходимо выбрать все названия столбцов из 1-ной таблицы в массив, где в строке с id = '$id' имеются какие-либо значения ( не нулл, не емпти), имеющие начало 'tr_'

    Как-то так.
    Спасибо.
     
  2. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.582
    Симпатии:
    1.484
    Пример бы... Какие столбцы, какие там могут быть значения.
    Сколько может быть строк с одинаковыми id?
    А то описание странное.

    Если я правильно понял задачку и в таблице не слишком много строк с id = '$id', то это лучше на пыхе делать. А на MYSQL под это дело придётся процедуру писать.
     
    Black Hat и __pes нравится это.
  3. __pes

    __pes

    Регистр.:
    10 май 2017
    Сообщения:
    307
    Симпатии:
    95
    да, через php удобнее, а таблицу саму можно посмотреть, тоже интересно.
     
  4. QuZ

    QuZ Постоялец

    Регистр.:
    18 июл 2009
    Сообщения:
    84
    Симпатии:
    49
    Через PHP - да, абсолютно согласен. Но у меня нет его вообще в данной задаче. Мне именно sql запрос надо. В самом худшем варианте - это его генерация будет отдельным проектом, подгрузка.. Не, ну это ужасно очень.
    <-------------- добавлено через 93 сек. -------------->
    Айдишники - уникальные. Около 50 000 штук сейчас. Столбцов в этой таблице - около 198 шт) (Просто увеличиваться кол-во их будет еще).
    Пример таблицы (всего 1-на штука). На тип данных, текст - не обращайте внимание, импорт делался. (Название колонки, Тип данных).
    tr_PROPERTY_272 text
    tr_PROPERTY_273 text
    tr_PROPERTY_270 text
    tr_PROPERTY_304 text
    tr_PROPERTY_268 text
    tr_PROPERTY_274 text
    tr_PROPERTY_275 text
    tr_PROPERTY_276 text
    tr_PROPERTY_277 text
    tr_PROPERTY_278 text
    tr_PROPERTY_279 text
    tr_PROPERTY_280 text
    tr_PROPERTY_281 text
    tr_PROPERTY_282 text
    tr_PROPERTY_283 text
    tr_PROPERTY_284 text
    Интерьер text
    tr_PROPERTY_285 text
    tr_PROPERTY_286 text
    tr_PROPERTY_287 text
    tr_PROPERTY_288 text
    Раздел text
    Каталог text
    tr_PROPERTY_289 text
    tr_PROPERTY_290 text
    tr_PROPERTY_291 text
    tr_PROPERTY_292 text
    tr_PROPERTY_293 text
    tr_PROPERTY_294 text
    tr_PROPERTY_295 text
    tr_PROPERTY_269 text
    tr_PROPERTY_296 text
    tr_PROPERTY_297 text
    tr_PROPERTY_298 text

    По данным. Данные сильно структурированы, по этому, из всех колонок, для одной строки заполнено около 20-30-ти таких полей. Тот механизм, который их принимает, он в цикле проверяет каждую ячейку, пустую, не пустую) и долго ее обрабатывает. Данной софтине, я максимум, могу скормить, какие колонки ему запрашивать. ( У нее селект идет по каждой колонке в пределах одной строки).

    Представленные значения - int\varchar. Других типов данных, которые занесены в данные колонки нет.
    За id - извиняюсь, просто автоинкримент, все дела)

    Вот соответственно, мне надо, чтобы мускул выдал все колонки, которые начинаются с tr_ и содержимое ячейки не NULL не empty.

    Сколько всего этих строк - я не знаю, но думаю, что больше 10 м. Сколько всего столбцов - я тоже не знаю. Буду если что кусками выбирать
     
    Последнее редактирование: 8 ноя 2017
  5. iden86

    iden86 Создатель

    Регистр.:
    30 окт 2017
    Сообщения:
    30
    Симпатии:
    11
    select * from tab_name where `id` like "%tr_%"
     
  6. Black Hat

    Black Hat

    Регистр.:
    15 май 2015
    Сообщения:
    155
    Симпатии:
    101
    Правильно понял: на вход id, и нужно сделать типа
    Код:
    SELECT * from table where id = :id
    
    Только вместо * должны выбираться только tr_, где не пусто и не NULL?
    И еще INT - не можеть быть "пусто", сравнивать с нулем или не надо?
     
  7. QuZ

    QuZ Постоялец

    Регистр.:
    18 июл 2009
    Сообщения:
    84
    Симпатии:
    49
    Надо подумать над Вашим предложением, но, думаю не пройдет ( на первый взгляд). Сейчас чуть поясню, о чем первоначально говорил. У меня есть строка, айди 5-ть, к примеру. Мне надо получить не значения из колонок для данной строки, а название самих колонок и желательно, в виде массива. Т.е. та злосчастная система может брать (для наглядности, как из файла по строкам (одна строка одна колонка) название ячейки и после уже сама делает туда запрос. Иначе, это творение 2000 годов института по исследованию живых организмов минимум по минуте тратит на обработку любой колонки из тех 300 + (судя по названию) и всех научных сотрудников это устраивало, а мой друг устал по пол дня тратить на это время.
     
  8. Black Hat

    Black Hat

    Регистр.:
    15 май 2015
    Сообщения:
    155
    Симпатии:
    101
    Моя экспериментальная табличка:
    Код:
    CREATE TABLE `discharged_table` (
      id INT(11) unsigned auto_increment,
      tr_PROPERTY_272 text,
      tr_PROPERTY_273 text,
      tr_PROPERTY_270 text,
      primary key(`id`)
    ) engine=innodb;
    
    INSERT INTO discharged_table VALUES
    (DEFAULT, 'data', 'data', 'data'),
    (DEFAULT, 'data', '', ''),
    (DEFAULT, 'data', NULL, ''),
    (DEFAULT, 'data', NULL, NULL),
    (DEFAULT, '', '', ''),
    (DEFAULT, NULL, NULL, NULL);
    

    Допустим, табличка такая:

    Код:
    mysql> SELECT * FROM discharged_table;
    +----+-----------------+-----------------+-----------------+
    | id | tr_PROPERTY_272 | tr_PROPERTY_273 | tr_PROPERTY_270 |
    +----+-----------------+-----------------+-----------------+
    |  1 | data            | data            | data            |
    |  2 | data            |                 |                 |
    |  3 | data            | NULL            |                 |
    |  4 | data            | NULL            | NULL            |
    |  5 |                 |                 |                 |
    |  6 | NULL            | NULL            | NULL            |
    +----+-----------------+-----------------+-----------------+
    
    Тогда запрос будет такой:
    Код:
    mysql> SELECT `id`, CONCAT_WS(',',
        ->   CASE WHEN tr_PROPERTY_272 IS NULL OR tr_PROPERTY_272 = '' THEN NULL ELSE 'tr_PROPERTY_272' END,
        ->   CASE WHEN tr_PROPERTY_273 IS NULL OR tr_PROPERTY_273 = '' THEN NULL ELSE 'tr_PROPERTY_273' END,
        ->   CASE WHEN tr_PROPERTY_270 IS NULL OR tr_PROPERTY_270 = '' THEN NULL ELSE 'tr_PROPERTY_270' END
        -> ) AS `not_empty_cols`
        -> FROM `discharged_table`;
    +----+-------------------------------------------------+
    | id | not_empty_cols                                  |
    +----+-------------------------------------------------+
    |  1 | tr_PROPERTY_272,tr_PROPERTY_273,tr_PROPERTY_270 |
    |  2 | tr_PROPERTY_272                                 |
    |  3 | tr_PROPERTY_272                                 |
    |  4 | tr_PROPERTY_272                                 |
    |  5 |                                                 |
    |  6 |                                                 |
    +----+-------------------------------------------------+
    
    Ну а разбить not_empty_cols в массив на PHP:
    Код:
    $cols = explode(',', $row['not_empty_cols']);
    
     
    alex_me нравится это.
  9. QuZ

    QuZ Постоялец

    Регистр.:
    18 июл 2009
    Сообщения:
    84
    Симпатии:
    49
    Огромное спасибо. Похоже на то, что необходимо. Единственное но - это придется описывать тогда в скуле каждую колонку ( ее название). Как я понимаю, добиться от скула выполнения данной задачи без явной передачи в запрос названия колонок, с которыми необходимо работать только указав что они в названии должны содержать tr_ не выйдет.
     
  10. Black Hat

    Black Hat

    Регистр.:
    15 май 2015
    Сообщения:
    155
    Симпатии:
    101
    Теоретически можно. Для этого делается хранимая процедура, где подготавливается выражение, а потом выполняется. Данные по названиям колонок в ней можно взять из информационной схемы. Однако, такую хранимую процедуру нельзя использовать с конструкцией WHERE, поэтому выведется вся таблица БД.