MySQL запрос, где встречаются все значения (вычитающий запрос) - PullRequest
0 голосов
/ 25 января 2012

Итак, у меня есть запрос на активную запись, который я делаю в PHP в рамках Codeigniter, где я хочу выбрать все записи (названные «дорожки» ниже), где встречается определенное значение в соединении («теги»)', которые связаны с дорожками - к каждой дорожке может быть привязано несколько тегов).Что мне интересно, так это то, что есть ли способ заставить запрос искать треки, с которыми связаны ВСЕ выбранные теги.Таким образом, вместо того, чтобы он получал все дорожки, которые имеют значение links.tag_id, равное 1, а затем получал все дорожки, имеющие значение links.tag_id, равное 2, он возвращал все дорожки, которые имели бы значение links.tag_id, равное 1, а также 2. По сути, этовычитающий запрос, в котором он сужает выбранные результаты по большему количеству добавляемых вами тегов.Вот что я пока делаю:

$this->db->select('tracks.id, 
                        tracks.name AS name, 
                        tracks.filename, 
                        tracks.url_name, 
                        tracks.file_path_high, 
                        tracks.filesize, 
                        tracks.categories,
                        tracks.duration, 
                        tracks.folder,
                        links.tag_id,
                        SUM(links.weight) AS total_weight,
                        tag_data.tag_name');

$this->db->distinct();
$this->db->from('music AS tracks');
$this->db->where_in('links.tag_id', array('1', '2');
$this->db->join('linked_tags AS links', 'links.track_id = tracks.id', 'inner');
$this->db->join('tags AS tag_data', 'tag_data.id = links.tag_id', 'inner');

1 Ответ

0 голосов
/ 25 января 2012

Вам нужно много раз присоединиться к таблице тегов для каждого тега, который вы хотите найти, и использовать псевдоним каждого тега в предложении where.Например, я бы сделал это:

$this->db->select('...');
$this->db->distinct();
$this->db->from('music AS tracks');
//Tag 1
$this->db->join('linked_tags AS links1', 'links1.track_id = tracks.id', 'inner');
$this->db->join('tags AS tag_data1', 'tag_data1.id = links1.tag_id AND tag_data1.tag = "tag1"', 'inner');
//Tag 2
$this->db->join('linked_tags AS links2', 'links2.track_id = tracks.id', 'inner');
$this->db->join('tags AS tag_data2', 'tag_data2.id = links2.tag_id AND tag_data2.tag = "tag2"', 'inner');
//Tag 3
$this->db->join('linked_tags AS links3', 'links3.track_id = tracks.id', 'inner');
$this->db->join('tags AS tag_data3', 'tag_data3.id = links3.tag_id AND tag_data3.tag = "tag3"', 'inner');

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

В этом случае INNER много раз присоединяется к таблицам LINKED_TAGS и TAGS и вынуждает INNER JOIN выполняться для определенного тега.Если тег не может быть найден для определенного объекта, внутреннее соединение не будет выполнено и, следовательно, просто не будет возвращено ... Вы можете добавить столько соединений, сколько вам нужно, но, очевидно, в определенный момент это может произойти при запросе.Производительность.

Дополнительные примеры использования этой же техники см. в следующем сообщении:

Расширенное соединение MySQL.Ускорение запроса

Удачи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...