Opened 21 months ago

Last modified 19 months ago

#1078 new дефект

Неправильная работа фильтра.

Reported by: alx Owned by: Denis_N
Priority: major Component: БД изделий АДС
Keywords: Cc:

Description

В r153/base на главной странице создаю фильтр, выводящий не тестированные изделия (то есть изделия, для которых в истории нет записей об успешном или неуспешном тестировании). В полученном списке вижу, например, изделие RM-48 s/n F00068, которое... имеет запись об успешном тестировании!

Attachments (1)

ss1.jpg (148.6 KB ) - added by alx 21 months ago.

Download all attachments as: .zip

Change History (11)

comment:1 by san, 21 months ago

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

in reply to:  1 ; comment:2 by alx, 21 months ago

Replying to san:

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

Не проблема. Если автор это подтвердит, я изменю тип тикета на "улучшение" и предложу передумать.

in reply to:  2 ; comment:3 by Denis_N, 21 months ago

По логике можно указать в фильтрах "не по истории", например фильтр "тестирование" у продуктов, а в нем статус "не тестировалось". И логика базы на данный момент сделана так, что не должно быть изделий у которых в ТБ "продукты" в столбце, например, "тестирование" стоит запись "Не тестировалось", а в "Истории" есть запись о тестировании. Понятно, что могут быть баги, или обстоятельства, при которых в базу вручную заносятся данные (например, по просьбе сотрудника). Я думаю, что нужно, например, "блокировать" возможность выбора фильтра "Тестирование" в Истории, когда в фильтрах у тб "Продукты" выбран текущий статус не тестировалось

Что скажете?

Version 3, edited 21 months ago by Denis_N (previous) (next) (diff)

in reply to:  3 comment:4 by alx, 21 months ago

Replying to Denis_N:

По логике можно указать в фильтрах "не по истории", например фильтр "тестирование" у продуктов, в котором можно выбрать статус "не тестировалось".

Такое условие (фильтр), конечно, указать можно. Только это другое условие. Это не то же самое, о чем написано в описании тикета. Насколько я понимаю, в описанном варианте фильтра будут выведены все записи таблицы products, у которых поле testing имеет значение notest. Но это не означает, что изделие никогда не тестировалось!

И логика базы на данный момент сделана так, что не должно быть изделий у которых в ТБ "продукты" в столбце, например, "тестирование" стоит запись "Не тестировалось", а в "Истории" есть запись о тестировании.

Если так, то логика базы на данный момент не соответствует постановке задачи - см. ticket:1061#comment:13 (последний абзац). :)

В данном случае столбец testing, а точнее, его значение notest и, главное, отображение этого значения в веб-интерфейсе как "не тестировалось", просто неудачно названо, что сбивает с толку. Значение notest означает, что изделие требует тестирования. Это не значит, что изделие никогда не тестировалось, вовсе нет. Изделию может требоваться, например, повторное тестирование после того, как уже после тестирования в нем было обнаружено несоответствие (я не знаю, правильно это или нет, мне эта логика непонятна, но задумано было так).

Я думаю, что нужно, например, "блокировать" возможность выбора фильтра "Тестирование" в Истории, когда в фильтрах у тб "Продукты" выбран текущий статус не тестировалось
Что скажете?

Я скажу, что это - покушение на свободу получения информации сотрудниками (в первую очередь менеджерами). Почему ты хочешь запретить делать определенные поисковые запросы? Что и почему ты хочешь скрыть? Это как-то подозрительно... :)

Я считаю, что любые (внутренне не противоречивые) условия имеют право на существование.

comment:5 by Denis_N, 21 months ago

Понял. Добавлю такой фильтр на главную

by alx, 21 months ago

Attachment: ss1.jpg added

in reply to:  5 comment:6 by alx, 21 months ago

Replying to Denis_N:

Добавлю такой фильтр на главную

??? Ничего не понимаю... Так ведь есть на Главной уже такой фильтр:


только он работает не совсем правильно...

comment:7 by alx, 21 months ago

Кажется я понял, в чем тут проблема!

В текущем веб-интерфейсе условие поиска для статуса записей в истории задается двумя чекбоксами ("успешно" и "неуспешно"), каждый из которых может быть отмечен или не отмечен - всего четыре возможных комбинации. Но этого недостаточно, так как возможных условий поиска больше! Кроме условий "записи с данным статусом имеются" и "записей с данным статусом нет" возможен еще вариант "не важно, есть или нет записей с таким статусом".

Я предполагал (так как нет мануала, где я это мог бы прочитать), что если отмеченный чекбокс означает условие "имеются записи с данным статусом" (и это действительно так работает), то противоположное (не отмеченное) состояние чекбокса означает противоположное условие - "не имеется записей с данным статусом", что, как мне кажется, было бы логично. Поэтому когда я сделал фильтр с двумя не отмеченными чекбоксами (кстати, это их значение по умолчанию!), я ожидал, что будут найдены изделия, не содержащие никаких записей о тестировании. Но сейчас я догадываюсь, что неотмеченный чекбокс, вероятно, означает "не важно", и это объясняет, почему мой фильтр не работал...

Предлагаю доработать поле "Статус записи в истории" таким образом, чтобы для каждого статуса был выбор не из двух, а из трех возможных вариантов - например заменить чекбокс на select.

comment:8 by Denis_N, 21 months ago

Да, это я и пытаюсь сделать и я столкнулся несовершенством этого мира и сейчас взорвется голова. Нужна Ваша помощь

Я пытался составить sql-запрос, который бы выбирал изделия из тб Продукты, у которых в тб История нет ни одной записи в столбце "Тип записи" со значением 'testing'. В поисках ответа на stackoverflow я пришел к этому:
-> select products.uid, products.serial from products where products.uid NOT IN(select uid from history where history.type_write = 'testing');
И это не работает. А выводит "Empty set()"

НО, если я создам таблицы, подобные таблицами История и Продукты, то всё работает:

create table accounts (

id_account int(11) NOT NULL AUTO_INCREMENT,
email varchar(50) NOT NULL,
password varchar(255) NOT NULL,
login varchar(255) DEFAULT NULL,
date_add date NOT NULL,
PRIMARY KEY (id_account)

)

CREATE TABLE accounts_status (

account_id int(11) NOT NULL,
service_id varchar(100) NOT NULL,
status tinyint(4) NOT NULL

)

insert into accounts (email, password, login, date_add) values ('sometext', 'sometext', 'sometext', now()) -- x3

mysql> select * from accounts;
+------------+----------+----------+----------+------------+
| id_account | email | password | login | date_add |
+------------+----------+----------+----------+------------+
| 1 | sometext | sometext | sometext | 2023-03-10 |
| 2 | sometext | sometext | sometext | 2023-03-10 |
| 3 | sometext | sometext | sometext | 2023-03-10 |
+------------+----------+----------+----------+------------+

mysql> insert into accounts_status (account_id, service_id, status) values (1, 'ok', 1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into accounts_status (account_id, service_id, status) values (1, 'fail', 1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into accounts_status (account_id, service_id, status) values (1, 'no', 1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into accounts_status (account_id, service_id, status) values (2, 'ok', 1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into accounts_status (account_id, service_id, status) values (2, 'testing', 1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into accounts_status (account_id, service_id, status) values (2, 'load', 1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into accounts_status (account_id, service_id, status) values (3, 'fail', 1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from accounts_status;
+------------+------------+--------+
| account_id | service_id | status |
+------------+------------+--------+
| 1 | ok | 1 |
| 1 | fail | 1 |
| 1 | no | 1 |
| 2 | ok | 1 |
| 2 | testing | 1 |
| 2 | load | 1 |
| 3 | fail | 1 |
+------------+------------+--------+
7 rows in set (0.00 sec)

mysql> select accounts.id_account, accounts.email from accounts where accounts.id_account NOT IN(select account_id from accounts_status where service_id = 'testing');
+------------+----------+
| id_account | email |
+------------+----------+
| 1 | sometext |
| 3 | sometext |
+------------+----------+
2 rows in set (0.00 sec)

Не знаете почему это может не работать для products и history?

Столбцы и типы:

mysql> show columns from products;
+----------+-------------------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------------------------------------------------------------------+------+-----+---------+----------------+
| UID | int | NO | PRI | NULL | auto_increment |
| type | varchar(100) | YES | | NULL | |
| name | varchar(100) | YES | | NULL | |
| serial | varchar(100) | NO | UNI | NULL | |
| date | date | YES | | NULL | |
| owner | varchar(100) | YES | | АДС | |
| location | enum('stock','shipped','develop','isolator','nelikvid','repair','work') | YES | | NULL | |
| testing | enum('ok','fail','notest') | YES | | notest | |
| otk | enum('ok','fail','nocheck') | YES | | nocheck | |
| mismatch | enum('yes','no') | YES | | no | |
| repair | varchar(100) | YES | | no | |
| comment | text | YES | | NULL | |
+----------+-------------------------------------------------------------------------+------+-----+---------+----------------+

mysql> show columns from history;
+--------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
| UID | int | YES | | NULL | |
| worker | varchar(100) | YES | | NULL | |
| date | datetime | YES | | NULL | |
| type_write | enum('record','otk','mismatch','testing','repair','shipping','transform') | YES | | NULL | |
| order_from | varchar(100) | YES | | NULL | |
| whom_order | varchar(100) | YES | | NULL | |
| location | enum('stock','shipped','develop','isolator','nelikvid','repair','work') | YES | | NULL | |
| number_order | varchar(100) | YES | | NULL | |
| status | enum('ok','fail') | YES | | NULL | |
| comment | text | YES | | NULL | |
| protocol | varchar(100) | YES | | NULL | |
| N | int | NO | PRI | NULL | auto_increment |
+--------------+---------------------------------------------------------------------------+------+-----+---------+----------------+

in reply to:  8 comment:9 by alx, 21 months ago

Replying to Denis_N:

Да, это я и пытаюсь сделать и я столкнулся несовершенством этого мира и сейчас взорвется голова.

Согласен. :) Чем дальше в лес - тем толще партизаны. :) Я тут сообразил, что ведь у нас еще не задается операция OR/AND для статусов проверок. А ведь "успешные ИЛИ неуспешные тестировния" и "успешные И неуспешные тестировния" - это два разных условия...

У меня уже мелькнула мысль, может быть проще было бы какой-то мета-язык для условий поиска реализовать (который потом переводить в SQL), а то в получившемся нагромождении чекбоксов и селектов никто не сможет разобраться... :(

Нужна Ваша помощь

Хм... Разве мы были не на "ты"? :)

Я пытался составить sql-запрос, который бы выбирал изделия из тб Продукты, у которых в тб История нет ни одной записи в столбце "Тип записи" со значением 'testing'. В поисках ответа на stackoverflow я пришел к этому:
-> select products.uid, products.serial from products where products.uid NOT IN(select uid from history where history.type_write = 'testing');
И это не работает. А выводит "Empty set()"

Скопировал без изменений запрос из твоего комментария - получил 3748 rows in set (0.573 sec).

Last edited 21 months ago by alx (previous) (diff)

comment:10 by alx, 19 months ago

Повторил поиск в r213/base, только на этот раз отметил оба чекбокса (и "Успешно", и "Не успешно"). Получил сообщение об ошибке: "Ошибка запроса в Продукты1: mysqli_queryColumn 'UID' in order clause is ambiguous".

Note: See TracTickets for help on using tickets.