Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Буквенно чисельный диапазон
Форумы портала PHP.SU » » Хранение данных, их вывод и обработка » Буквенно чисельный диапазон

Страниц (1): [1]
 

1. snikers987 - 15 Октября, 2014 - 10:12:49 - перейти к сообщению
Приветствую.

Стоит задача:
Пользователь может ввести в поле "от" и "до" диапазон значений содержащий латинскую букву (A-Z) в начале или в конце строки и цифры. Например, диапазон может быть следующий:

Цитата:

A00001 - B99999
или
00001A - 99999B


Как эти диапазоны лучше хранить в базе, для максимально удобной проверки, входит ли значение N в какой-то из диапазонов.

Спасибо.
2. RickMan - 15 Октября, 2014 - 10:16:08 - перейти к сообщению
А пользователь может ввести A00001 - 99999B ?
3. snikers987 - 15 Октября, 2014 - 10:20:10 - перейти к сообщению
RickMan пишет:
А пользователь может ввести A00001 - 99999B ?


нет
4. RickMan - 15 Октября, 2014 - 10:20:12 - перейти к сообщению
Вообще решением я думаю будет пройтись посимвольно и сверить.
(Добавление)
А что если сравнивать эти два числа, исходя из того, что они в 16-ричной системе? Тогда и сравнивать не сложно.
5. Sail - 15 Октября, 2014 - 10:29:33 - перейти к сообщению
RickMan, "содержащий латинскую букву (A-Z)". "Гранаты не той системы" Улыбка
snikers987, 12345G больше, чем 99999B, или не больше?
6. Мелкий - 15 Октября, 2014 - 10:31:13 - перейти к сообщению
Можно чуть про предметную область? Может, получится подсказать что-нибудь более адекватное.

Буква есть всегда, только одна? По каким правилам её сравнивать?
Решение в лоб:
is_letter_first - bool, начинается ли диапазон с буквы
Пара bigint, в которых первые или последние два десятичных знака (соответственно is_letter_first) отдать под числовой идентификатор соответствующей буквы. Остальные знаки будут хранить собственно число. Начало и конец диапазона, собственно.
7. RickMan - 15 Октября, 2014 - 10:41:21 - перейти к сообщению
Sail Ну и будет побольше система, что здесь плохово? Логика остается преждней.
8. snikers987 - 15 Октября, 2014 - 10:44:34 - перейти к сообщению
Мелкий пишет:
Можно чуть про предметную область? Может, получится подсказать что-нибудь более адекватное.

Буква есть всегда, только одна? По каким правилам её сравнивать?
Решение в лоб:
is_letter_first - bool, начинается ли диапазон с буквы
Пара bigint, в которых первые или последние два десятичных знака (соответственно is_letter_first) отдать под числовой идентификатор соответствующей буквы. Остальные знаки будут хранить собственно число. Начало и конец диапазона, собственно.


Что бы долго не объяснять, это некие медицинские коды процедур вот: http://en[dot]wikipedia[dot]org/wiki/Cur[dot][dot][dot]ural_Terminology

Там могут быть значения как с буквами, так и без них совсем (т.е. только цифры), но в каждом диапазоне, значение A и B всегда по одной схеме, т.е. если с буквой то оба значения с ней и буква в одинаковом месте, если без буквы, то оба значения без буквы. Суть в том, что при создании жалобы (обращение в страховую), вводится, среди прочего, этот код(ы) , при этом нужно проверять, входит, ли введенный код, в какой либо диапазон, если да, то выполняются некоторые действия.

Пока, самым адекватным решением, мне кажется, приводить все буквы к числам (т.е. 1-26), и хранить их в отдельных полях базы данных, и сравнивать все как десятичные числа.
(Добавление)
Sail пишет:

snikers987, 12345G больше, чем 99999B, или не больше?


больше
9. Sail - 15 Октября, 2014 - 11:17:44 - перейти к сообщению
snikers987 пишет:
приводить все буквы к числам (т.е. 1-26)

Неужели, есть разница, буквы сравнивать (латинские), или числа?!
Раз уж 12345G больше, чем 99999B, то действительно придётся разделять буку и число (строка с лидирующими нулями).
Вот ещё вариант:
- признак наличия буквенного символа (0 - нет, 1 - в начале, 2 - в конце)
- числовая часть кода
- буквенный символ (или просто пробел).
Сравнивать со строками: 'буквенный символ'.'числовая часть кода'.
Признак наличия актуален для корректного отображения кода в форме (отчёте).
****
Впрочем, и хранить можно в одной строке... обрабатывая буквенный символ при выводе, в зависимости от признака... Улыбка
И сравнивать, как предложил RickMan.
10. snikers987 - 15 Октября, 2014 - 11:27:47 - перейти к сообщению
Sail пишет:

Неужели, есть разница, буквы сравнивать (латинские), или числа?!


Ну вообще-то как бы есть. Если от A до С, а нужна B, например.
11. Sail - 15 Октября, 2014 - 11:43:34 - перейти к сообщению
snikers987 пишет:
Sail пишет:

Неужели, есть разница, буквы сравнивать (латинские), или числа?!


Ну вообще-то как бы есть. Если от A до С, а нужна B, например.

И в чём проблема?
Например:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE `extable` (
  2.   `id` int(11) NOT NULL AUTO_INCREMENT
  3. , `value1` varchar(6) NOT NULL DEFAULT ''
  4. , `value2` varchar(6) NOT NULL DEFAULT ''
  5. ,  PRIMARY KEY (`id`)
  6. );
  7. INSERT INTO `extable` (`value1`, `value2`) VALUES ('A00000', 'C99999');
  8. SELECT * FROM `extable` WHERE 'B12378' BETWEEN `value1` AND `value2`;
  9. SELECT * FROM `extable` WHERE 'D12378' BETWEEN `value1` AND `value2`;
  10.  
12. snikers987 - 15 Октября, 2014 - 12:42:46 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. INSERT INTO `extable` (`value1`, `value2`) VALUES ('A1', 'Z9');
  3. SELECT * FROM `extable` WHERE 'Y10' BETWEEN `value1` AND `value2`;
  4.  


Y10 не входит в диапазон A1 - Z9 , а в Вашем варианте - входит.
(Добавление)
Всем спасибо. Задача решена следующим образом:

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `test_table` (
  3.   `id` int(11) NOT NULL AUTO_INCREMENT,
  4.   `index_a` int(2) DEFAULT NULL,
  5.   `index_b` int(2) DEFAULT NULL,
  6.   `value_a` varchar(255) DEFAULT NULL,
  7.   `value_b` varchar(255) DEFAULT NULL,
  8.   `index_after` tinyint(1) DEFAULT '0',
  9.   PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
  11.  
  12. -- ----------------------------
  13. -- Records of test_table
  14. -- ----------------------------
  15. INSERT INTO `test_table` VALUES ('1', '1', '2', '10002', '20002', '0');
  16.  


index_a и index_b - содержит порядковый номер буквы (1-26)
value_a и value_b - содержит числовую часть кода, в начало которой добавлен числовой индекс буквы.
index_after - хранит позицию буквенного индекса в строке (0 - начало, 1- конец)

затем можно искать, например код A0003, можно вот так:

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT * FROM `test_table` WHERE (10003 BETWEEN `value_a` AND `value_b`) AND (1 BETWEEN `index_a` AND `index_b`) AND index_after=0;
  3.  


Отдельное спасибо Мелкий.

P.S. Таблица тестовая, не обращайте внимания на именование полей Подмигивание

 

Powered by ExBB FM 1.0 RC1