За последние 24 часа нас посетили 8810 программистов и 695 роботов. Сейчас ищут 136 программистов ...

Выборка из базы mysql по точному значению из текста в столбце (текст-список через запятую)

Тема в разделе "MySQL", создана пользователем dich40000, 14 янв 2020.

Метки:
  1. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Всем привет и хорошего настроения!

    Столкнулся с простой задачей, но но не доходит до меня как лучше это реализовать.
    Задача такова.

    Нужно обратиться к базе mysql и найти строки в которых в столбце city содержится город "city2" из перечисленных через запятую городов в ячейке.

    Имею ввиду запрос типа SELECT * from table1 WHERE city="city2"

    Строки выглядят таки образом:
    table1
    id----city----------------------------------------------region
    0-----city1,city2,city3,city4,city5-----------------region1
    1-----city6,city7,city2,city8,city9-----------------region2
    2-----city10,city11,city12,city13,city14---------region3

    В первой и второй сроке есть этот город city2, а в 3й нет. Нужно получить строки в которых он есть [​IMG]

    Использовать mysql запрос или же поместить всю базу в массив и воспользоваться поиском по массиву?
    Какой вариант лучше и как его реализовать? Или же ваш вариант. Рассмотрю любые [​IMG]
    Спасибо!
     
  2. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    @dich40000, есть отличный вариант перед тем как что-то делать, сначала выучить теорию, а потом переходить к практике.
    Начни с гугления, что такое нормализация бд, подумай каким образом ты нарушил её первый закон и почему он первый и почему он ЗАКОН.
     
  3. Roman __construct

    Roman __construct Активный пользователь

    С нами с:
    27 апр 2019
    Сообщения:
    1.244
    Симпатии:
    110
    Бро, скажи, а чем ты все это время занимался, если не секрет? :D

    Тебе нужно использовать это: http://unetway.com/tutorial/sql-operator-like/
     
    dich40000 нравится это.
  4. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Спасибо, за помощь. Про оператор Like знаю, думал можно ли это реализовать с помощью других операторов или like вполне достаточно?
    --- Добавлено ---
    Имеете в виду, что запись через запятую не стоит использовать, а нужно создать дополнительные строки с одним значением в ячейке?
     
    #4 dich40000, 14 янв 2020
    Последнее редактирование: 14 янв 2020
  5. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    Да, только не просто дополнительные строки, а строки в другой таблице и отношение "один ко многим". Ну и конечно же учиться объединять эти таблицы пользуясь конструкцией JOIN.
    А про LIKE лучше вспоминать как можно реже.
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    9.985
    Симпатии:
    939
    Адрес:
    там-сям
    @Valick прав. но я таки дам плохой (тормозной) но рабочий вариант решения: функция mysql find_in_set() а like тут точно не подойдёт.

    таки делай в нормальной форме. не привыкай к костылям!
    --- Добавлено ---
    @dich40000
    --- Добавлено ---
    5 сообщений вместе с сегодняшними и беджик "активный пользователь". какая ирония!
     
    Roman __construct нравится это.
  7. Roman __construct

    Roman __construct Активный пользователь

    С нами с:
    27 апр 2019
    Сообщения:
    1.244
    Симпатии:
    110
    Вполне достаточно, да.

    Хотя вон камрад artoodetoo что-то пишет про скорость - тут ничего уже не скажу, насчет скорости ему видней - он с SQL больше дела имеет.
    --- Добавлено ---
    ...можешь по идее еще это поле сделать в формате JSON и паковать списки в этот формат - так будет логичнее всего.

    Но таки LIKE по слухам быстрее будет)) это может иметь значение при больших выборках
     
  8. acho

    acho Активный пользователь

    С нами с:
    28 дек 2016
    Сообщения:
    788
    Симпатии:
    185
    Адрес:
    Санкт-Петербург
    like - плохая история. О нём вспоминать надо как можно реже.
    Лучше всего таблицу нормализовать. Самый адекватный подход.
    Хуже = find_in_set.
    JSON - неплохо, но понадобятся ещё телодвижения:
    просто сделать поле json будет недостаточно. Во-первых, структура данных должна быть изменена, во-вторых надо будет ещё создавать виртуальные генерируемые поля из этого json и эти виртуальные поля добавлять в индекс и поиск выполнять уже по ним.

    В общем лучший вариант - нормализовать таблицу.
     
    dich40000 нравится это.
  9. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Спасибо за советы. Возможно если я расскажу свою задумку, то вы вообще отговорите меня от лепки этого костыля.

    Смотрите вообщем я преследую такую задачу:

    Человека открывает на сайте форму поиска и указывает два города 1й из которого хочет ехать а 2й куда ехать

    Например есть маршрут из города А в город F есть идентификатор маршрута и цена его 100$
    A-->F стоимость 100$, но между этими городами есть промежуточные B C D E
    Человек находится в городе С и хочет уехать в F (А-b-C-d-e-F). Но отдельного маршрута из C в F нет, есть только маршрут A->F с промежуточными остановками.

    Когда человек вводит в поиск хочу поехать из C в F, то программа должна понять что это промежуток из рейса A F, так как у них есть общий идентификатор например id=1, поездка из D в F будет также относиться к рейсу A F и каждая другая поездка.
    а именно в базе должно быть такое кол-во строк (количество рейсов)
    id__Откуда__Куда__рейс__цена
    1___A______B_____1_____20
    2___A______C_____1_____30
    3___A______D_____1_____40
    4___A______E_____1_____50
    5___A______F_____1_____100
    6___B______C_____1_____10
    7___B______D_____1_____20
    8___B______E_____1_____30
    9___B______F_____1_____80
    и тд. вообщем записей будет в базе просто дохрена, особенно если промежуточных городов еще больше! Сколько промежуточных городов столько же и поездок из каждого начального города во все последующие.

    я же хочу сделать чтоб в базе было 2 таблицы 1я-рейсы, 2я цены.
    В таблице Рейсы была только одна строка и в ней хранились рейс и все промежуточные города а в таблице цены цены на все промежуточные поездки этого рейса (название таблицы цены и есть idрейса)

    Рейсы
    id__Откуда__Куда__рейс__цена__промежуточные__idрейса
    1
    ___A______F_____1_____100____A,B,C,D,E,F_______ценыAF
    2___G______X_____2_____120____H,I,J,K,L,M,N,O,P__ценыGX

    таблица ценыAF
    id__city_to__A___B___C___D___E
    1
    ___A______--___--___--___--___--
    2___B______20__--___--___--____--
    3___C______30__10__--___--____--
    4___D______40__20__10__--____--
    5___E______50__30__20__10___--
    6___F______100_80__30__20___10

    Например поездка C F на пересечении строки и столбца получаем цену.
    Цену получаем запросом вида:

    Код (Text):
    1. mysql_query("SELECT C FROM ценыAF WHERE city_to='F' ")
    В результате на пересечении столбца С и сроки F цена 30


    Вообщем человек вводит в поиск хочу поехать из C в F

    Алгоритм такой:

    1. Программа поиска начинает искать город сначала из рейсов
    2. Если не нашла город среди рейсов, то начинает искать среди промежуточных городов внутри каждого рейса (а вот рейсов строк в базе может быть много).
    3. Если находит среди промежуточных, то берет idрейса=ценыAF и по этому idрейса находит таблицу ценыAF с ценами
    4. Ну и на пересечении столбцов и строк C F выбранных городов получает цену.

    Во такая идея. Прошу не ругаться и не матюкать. Изобретаю велосипед, так как не могу придумать как это лучше реализовать и не могу найти примера. Спасибо заранее за советы.
     
  10. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    Что не понятно в словах "теория" и "погугли"?
    Первая таблица рейсы trip
    t_id | t_name | t_description
    Вторая таблица поездки run
    r_id | t_id | b_id_from | b_id_to | r_price
    Третья таблица населённые пункты (посадка) board
    b_id | b_name | b_description

    Это отношение многие ко многим, угадай которая из этих таблиц является таблицей связи.
     
  11. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    @dich40000, но в целом задача сложнее чем кажется. Это станет понятно при попытке создать маршрут с пересадками с одного рейса на другой.
    Немного теории


    И ещё куча информации, к примеру:
    http://www.cyberforum.ru/sql-server/thread2239397.html
     
    #11 Valick, 15 янв 2020 в 00:06
    Последнее редактирование: 15 янв 2020 в 00:18
    dich40000 и romach нравится это.
  12. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Если я правильно понял, то на примере выглядит это так

    Первая таблица рейсы trip
    t_id | t_name | t_description

    0 | рейс Москва-Киев | id_1
    1 | Рейс Москва-Питер| id_2

    Вторая таблица поездки run
    r_id | t_id | b_id_from | b_id_to | r_price

    0 | 0 | Москва | Киев | 100$

    Третья таблица населённые пункты (посадка) board
    b_id | b_name | b_description

    0 | Москва | id_1
    1 | Киев | id_1
    2 | Харьков| id_1
    3 | Питер | id_2

    Человек ищет поездку Москва-Харьков, попадает в таблицу board у Москвы b_description=id_1 и у Харьков b_description=id_1, значит находим в таблице trip строку с t_description=id_1 и понимаем что это рейс Москва-Киев, берем t_id=0 и попадаем в таблицу run в строку где t_id=0 и получаем маршрут МОСКВА-КИЕВ и цену?
     
  13. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    @dich40000, вот прям даже не рядом.
     
  14. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Посмотрел про теорию графов, дядька доступно объясняет про волновой алгоритм, но я не могу понять связь с нашей темой.

    Помогите, пожалуйста разобрать на примере с вашими таблицами.
     
  15. Roman __construct

    Roman __construct Активный пользователь

    С нами с:
    27 апр 2019
    Сообщения:
    1.244
    Симпатии:
    110
    У меня сейчас 4 утра и я мало что понял с первого прочтения, а на второе сил у меня уже не хватит)) однако что-то я все-таки ухватил с первого раза)))) и скажу вот чего:

    - Нужно делать отдельную таблицу, где будут перечислены все эти отношения

    что-то типа

    regions

    1 -- region
    2 -- region1

    cities

    1 -- city1
    2 -- city5
    3 -- city4

    region_cities

    1 -- 1
    2 -- 1
    2 -- 3

    эт оптимальное будет для последующих выборок

    остальное тебе Маус расскажет, он хотя и малохольный, но парень по сути добрый :D
     
    dich40000 нравится это.
  16. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    При всём желании у меня банально нет столько времени, что бы разжёвывать каждую букву. Намекну что таблица связи должна содержать поездки A->B, A->C, A->D, A->E, B->C, B->D, B->E и тд. (продолжи весь список если понял)

    P.S. Это самый простой вариант реализации. Но приходиться прописать каждый отрезок пути
     
    dich40000 нравится это.
  17. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Этого я и боялся, что придется писать каждый отрезок в строку)
    Спасибо большое за поддержку. Черпанул нового!
     
  18. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    9.985
    Симпатии:
    939
    Адрес:
    там-сям
    Просто для информации, есть специализированные СУБД для работы с графами. Например Neo4j
     
    Roman __construct и dich40000 нравится это.
  19. miketomlin

    miketomlin Активный пользователь

    С нами с:
    9 авг 2016
    Сообщения:
    2.228
    Симпатии:
    354
    @Valick, ТСу, как я понял, пересадки не нужны.
    --- Добавлено ---
    Причем по каждому рейсу и обоим направлениям. Это норм.
    --- Добавлено ---
    Не обратил внимание на пост Валика. Достаточно отрезков со смежными НП или несмежными, когда в промежуточных между ними нет остановок.
     
  20. Roman __construct

    Roman __construct Активный пользователь

    С нами с:
    27 апр 2019
    Сообщения:
    1.244
    Симпатии:
    110
    Этого не надо бояться - к этому надо привыкать )) потому что это - нормально.

    Вообще, подожди, мб еще кто чего предложит - я ведь отнюдь не гений SQL))) Просто иногда приходится иметь с этим дело, не более.
     
  21. Roman __construct

    Roman __construct Активный пользователь

    С нами с:
    27 апр 2019
    Сообщения:
    1.244
    Симпатии:
    110
    Кстати, не поленись:

    http://javabit.ru/любимые-задачки-по-sql-связь-многие-ко-мн/

    Написано вроде как простым понятным языком.

    Это как раз твой случай.

    Вообще это типовая задача, и если вдруг твоя жизнь сложится неудачно и ты всегда так и будешь программистом)) то ты столкнешься с этим еще раз 100500 - имеет смысл разобраться полностью уже сейчас.
    --- Добавлено ---
    //да, промотал страницу до конца - отличный текст! Респект чуваку.
     
  22. dich40000

    dich40000 Активный пользователь

    С нами с:
    9 июн 2015
    Сообщения:
    10
    Симпатии:
    0
    Спасибо, ознакомлюсь!
     
  23. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.608
    Симпатии:
    266
    Далеко не лучший вариант повествования, хотя бы потому, что в итоге так и осталось перекрёстное объединение без левого или на худой конец правого.