Выберите строки из таблицы, где id находится в списке через запятую в другой таблице - PullRequest
0 голосов
/ 29 июля 2011

У меня есть эти два запроса, которые я хочу объединить, но я недостаточно квалифицирован, чтобы это сделать.

Кто-нибудь может мне помочь?

это выбор строки, которая соответствуетпоиск, который содержит столбцы cids, которые, в свою очередь, мне нужно использовать во втором запросе

SELECT cids,tp FROM searches_done where (keyword='keyword' and city='city' and page='page' and ipp='ipp') LIMIT 1

, этот запрос выбирает фактические строки результатов, в которых сравнивается идентификатор каждой компании сЗначения, разделенные столбцами, которые мы получили в первом запросе (cids), к нему необходимо прикрепить столбец tp из первого запроса к каждому результату

SELECT c.*,s.tp FROM companies c WHERE c.id in (cids)

, в настоящее время он работает ся запускаю два запроса (по коду) и использую результаты, полученные из первого запроса во втором запросе.

searches_done table structure:

id - autoincrement unique int  
keyword - varchar(255) - keyword that was searched
page - int - paging page ( i.e: page=0 its the first page etc.. )
city - varchar(255) - keyword for city that was searched 
cids - text - comma seperated values of the companies ids 
                ( that were found matching this search )   
tp - int - total pages found
ipp - int - itemsperpage ( a search could be done with only 10 items per page
                         , so diffrent results might be found with 10/100 )

Сейчас я работаю над созданием новой таблицы, которая будет содержать sd_id, c_id для нормализациибаза данных: \

Ответы [ 2 ]

4 голосов
/ 29 июля 2011

Функция FIND_IN_SET() может использоваться:

SELECT ...
FROM companies c
  JOIN searches_done sd
    ON FIND_IN_SET( c.id, sd.cids) > 0
WHERE sd.keyword = 'keyword' 
  AND sd.city = 'city'
  AND sd.page = 'page'
  AND sd.ipp = 'ipp'

Но вы должны действительно нормализовать таблицу. От использования списков через запятую есть несколько преимуществ.


Как перенести данные в нормализованную таблицу связей:

--- create table
CREATE TABLE search_companies
( sd_id INT NOT NULL
, c_id INT NOT NULL
, PRIMARY KEY (sd_id, c_id)
, FOREIGN KEY sd_id REFERENCES searches_done(id)    --- if you use InnoDB
, FOREIGN KEY c_id REFERENCES companies(id)         --- 
) ;

--- transfer data
INSERT INTO search_companies
    (sd_id, c_id)
SELECT DISTINCT
    sd.id, c.id
FROM companies c
  JOIN searches_done sd
    ON FIND_IN_SET( c.id, sd.cids) > 0

Тогда ваш запрос будет использовать простые JOIN:

SELECT ...
FROM companies c
  JOIN searches_companies sc
    ON sc.c_id = c.id
  JOIN searches_done sd
    ON sd.id = sc.sd_id 
WHERE sd.keyword = 'keyword' 
  AND sd.city = 'city'
  AND sd.page = 'page'
  AND sd.ipp = 'ipp'

После проверки, что все в порядке и все запросы (SELECTs, INSERTs, DELETEs, UPDATEs) работают нормально, вы можете удалить поле cids.


Здесь есть хороший ответ на вопрос: действительно ли плохо хранить список, разделенный запятыми, в столбце базы данных?

1 голос
/ 29 июля 2011

Вы можете почти полностью покинуть таблицу search_done:

структура таблицы поисков:

id - autoincrement unique int
keyword - varchar(255) 
page - int 
city - varchar(255) 
tp - int 
ipp - int 

Затем добавьте еще одну таблицу:

searches_company:

search_id int foreign key searches_done.id
company_id int foreign key company.id

Затем вы можете объединить две таблицы, чтобы получить результаты:

SELECT c.id, tp 
FROM companies c
INNER JOIN searches_company sc ON c.id = sc.company_id
INNER JOIN searches_done sd ON sc.search_id = sd.id
WHERE ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...