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

QuZ

Постоялец
Регистрация
18 Июл 2009
Сообщения
86
Реакции
50
Добрый вечер. Мне необходим запрос следующего рода. Готов отблагодарить за него.

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

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

latteo

Эффективное использование PHP, MySQL
Регистрация
27 Фев 2008
Сообщения
1.603
Реакции
1.565
Пример бы... Какие столбцы, какие там могут быть значения.
Сколько может быть строк с одинаковыми id?
А то описание странное.

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

__pes

Постоялец
Регистрация
10 Май 2017
Сообщения
313
Реакции
118
да, через php удобнее, а таблицу саму можно посмотреть, тоже интересно.
 

QuZ

Постоялец
Регистрация
18 Июл 2009
Сообщения
86
Реакции
50
да, через php удобнее, а таблицу саму можно посмотреть, тоже интересно.
Через PHP - да, абсолютно согласен. Но у меня нет его вообще в данной задаче. Мне именно sql запрос надо. В самом худшем варианте - это его генерация будет отдельным проектом, подгрузка.. Не, ну это ужасно очень.
<-------------- добавлено через 93 сек. -------------->
Пример бы... Какие столбцы, какие там могут быть значения.
Сколько может быть строк с одинаковыми id?
А то описание странное.

Если я правильно понял задачку и в таблице не слишком много строк с id = '$id', то это лучше на пыхе делать. А на MYSQL под это дело придётся процедуру писать.
Айдишники - уникальные. Около 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 м. Сколько всего столбцов - я тоже не знаю. Буду если что кусками выбирать
 
Последнее редактирование:

iden86

Создатель
Регистрация
30 Окт 2017
Сообщения
26
Реакции
11
select * from tab_name where `id` like "%tr_%"
 

Black Hat

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

QuZ

Постоялец
Регистрация
18 Июл 2009
Сообщения
86
Реакции
50
Правильно понял: на вход id, и нужно сделать типа
Код:
SELECT * from table where id = :id
Только вместо * должны выбираться только tr_, где не пусто и не NULL?
И еще INT - не можеть быть "пусто", сравнивать с нулем или не надо?
Надо подумать над Вашим предложением, но, думаю не пройдет ( на первый взгляд). Сейчас чуть поясню, о чем первоначально говорил. У меня есть строка, айди 5-ть, к примеру. Мне надо получить не значения из колонок для данной строки, а название самих колонок и желательно, в виде массива. Т.е. та злосчастная система может брать (для наглядности, как из файла по строкам (одна строка одна колонка) название ячейки и после уже сама делает туда запрос. Иначе, это творение 2000 годов института по исследованию живых организмов минимум по минуте тратит на обработку любой колонки из тех 300 + (судя по названию) и всех научных сотрудников это устраивало, а мой друг устал по пол дня тратить на это время.
 

Black Hat

Постоялец
Регистрация
15 Май 2015
Сообщения
167
Реакции
112
Моя экспериментальная табличка:
Код:
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']);
 

QuZ

Постоялец
Регистрация
18 Июл 2009
Сообщения
86
Реакции
50
Моя экспериментальная табличка:
Код:
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']);

Огромное спасибо. Похоже на то, что необходимо. Единственное но - это придется описывать тогда в скуле каждую колонку ( ее название). Как я понимаю, добиться от скула выполнения данной задачи без явной передачи в запрос названия колонок, с которыми необходимо работать только указав что они в названии должны содержать tr_ не выйдет.
 

Black Hat

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