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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Буквенно чисельный диапазон

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
snikers987
Отправлено: 15 Октября, 2014 - 10:12:49
Post Id



Участник


Покинул форум
Сообщений всего: 1239
Дата рег-ции: Сент. 2011  
Откуда: Крым


Помог: 25 раз(а)




Приветствую.

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

Цитата:

A00001 - B99999
или
00001A - 99999B


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

Спасибо.


-----
Когда всматриваешься в тёмную бездну, учти, что кто-то может смотреть на тебя из неё...
 
My status
 Top
RickMan
Отправлено: 15 Октября, 2014 - 10:16:08
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




А пользователь может ввести A00001 - 99999B ?
 
 Top
snikers987
Отправлено: 15 Октября, 2014 - 10:20:10
Post Id



Участник


Покинул форум
Сообщений всего: 1239
Дата рег-ции: Сент. 2011  
Откуда: Крым


Помог: 25 раз(а)




RickMan пишет:
А пользователь может ввести A00001 - 99999B ?


нет


-----
Когда всматриваешься в тёмную бездну, учти, что кто-то может смотреть на тебя из неё...
 
My status
 Top
RickMan
Отправлено: 15 Октября, 2014 - 10:20:12
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




Вообще решением я думаю будет пройтись посимвольно и сверить.
(Добавление)
А что если сравнивать эти два числа, исходя из того, что они в 16-ричной системе? Тогда и сравнивать не сложно.
 
 Top
Sail
Отправлено: 15 Октября, 2014 - 10:29:33
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




RickMan, "содержащий латинскую букву (A-Z)". "Гранаты не той системы" Улыбка
snikers987, 12345G больше, чем 99999B, или не больше?
 
 Top
Мелкий Супермодератор
Отправлено: 15 Октября, 2014 - 10:31:13
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Можно чуть про предметную область? Может, получится подсказать что-нибудь более адекватное.

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


-----
PostgreSQL DBA
 
 Top
RickMan
Отправлено: 15 Октября, 2014 - 10:41:21
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




Sail Ну и будет побольше система, что здесь плохово? Логика остается преждней.
 
 Top
snikers987
Отправлено: 15 Октября, 2014 - 10:44:34
Post Id



Участник


Покинул форум
Сообщений всего: 1239
Дата рег-ции: Сент. 2011  
Откуда: Крым


Помог: 25 раз(а)




Мелкий пишет:
Можно чуть про предметную область? Может, получится подсказать что-нибудь более адекватное.

Буква есть всегда, только одна? По каким правилам её сравнивать?
Решение в лоб:
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, или не больше?


больше

(Отредактировано автором: 15 Октября, 2014 - 10:49:46)



-----
Когда всматриваешься в тёмную бездну, учти, что кто-то может смотреть на тебя из неё...
 
My status
 Top
Sail
Отправлено: 15 Октября, 2014 - 11:17:44
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




snikers987 пишет:
приводить все буквы к числам (т.е. 1-26)

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

(Отредактировано автором: 15 Октября, 2014 - 11:21:54)

 
 Top
snikers987
Отправлено: 15 Октября, 2014 - 11:27:47
Post Id



Участник


Покинул форум
Сообщений всего: 1239
Дата рег-ции: Сент. 2011  
Откуда: Крым


Помог: 25 раз(а)




Sail пишет:

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


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


-----
Когда всматриваешься в тёмную бездну, учти, что кто-то может смотреть на тебя из неё...
 
My status
 Top
Sail
Отправлено: 15 Октября, 2014 - 11:43:34
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




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.  
 
 Top
snikers987
Отправлено: 15 Октября, 2014 - 12:42:46
Post Id



Участник


Покинул форум
Сообщений всего: 1239
Дата рег-ции: Сент. 2011  
Откуда: Крым


Помог: 25 раз(а)




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. Таблица тестовая, не обращайте внимания на именование полей Подмигивание

(Отредактировано автором: 15 Октября, 2014 - 14:10:55)



-----
Когда всматриваешься в тёмную бездну, учти, что кто-то может смотреть на тебя из неё...
 
My status
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Хранение данных, их вывод и обработка »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB