2010-09-16 3 views
0

У меня есть следующая MySQL схема таблицы:Помощи со сложными условиями соединения

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 

-- 
-- Database: `network` 
-- 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `contexts` 
-- 

CREATE TABLE IF NOT EXISTS `contexts` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `keyword` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `neurons` 
-- 

CREATE TABLE IF NOT EXISTS `neurons` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; 

-- -------------------------------------------------------- 

-- 
-- Table structure for table `synapses` 
-- 

CREATE TABLE IF NOT EXISTS `synapses` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `n1_id` int(11) NOT NULL, 
    `n2_id` int(11) NOT NULL, 
    `context_id` int(11) NOT NULL, 
    `strength` double NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; 

Что SQL я могу написать, чтобы получить все Нейроны, связанные с определенным контекстом наряду с суммой колонки прочности для синапсов, связанных с каждый нейрон?

Я использую следующий запрос, который возвращает сумму синапсов, связанных с одним нейроном. Мне нужно, чтобы получить информацию для всех нейронов:

/* This query finds how strongly the neuron with id 1 is connected to the context with keyword ice cream*/ 

SELECT SUM(strength) AS Strength FROM 
synapses 
JOIN contexts AS Context ON synapses.context_id = Context.id 
JOIN neurons AS Neuron ON Neuron.id = synapses.n1_id OR Neuron.id = synapses.n2_id 
WHERE Neuron.id = 1 AND Context.keyword = 'ice cream' 

Например, этот запрос возвращает одну строку, где сила 2. В идеале, я мог бы иметь один столбец для neurons.id, один для neurons.name , и один для SUM (synapses.strength) с одной записью для каждого отдельного нейрона.

ответ

1

Использование:

SELECT DISTINCT 
      n.*, 
      COALESCE(x.strength, 0) AS strength 
    FROM NEURONS n 
    JOIN SYNAPSES s ON n.id IN (s.n1_id, s.n2_id) 
    JOIN CONTEXTS c ON c.id = s.context_id 
LEFT JOIN (SELECT c.id AS c_id, 
        n.id AS n_id, 
        SUM(strength) AS Strength 
      FROM SYNAPSES s 
      JOIN CONTEXTS c ON c.id = s.context_id 
      JOIN NEURONS n ON n.id IN (s.n1_id, s.n2_id) 
     GROUP BY c.id, n.id) x ON x.c_id = c.id 
           AND x.n_id = n.id 
+0

Этот запрос быстрее. Я попробовал оба с добавленным WHERE context.keyword LIKE '% ice%' ... Mike's sql занял 0.0218 с. Код Ponies занял 0.0007 сек. Почему этот запрос намного быстрее? – Adam

+0

@Adam: Вероятно, имеет отношение к другому синтаксису (поменяется ИЛИ для предложения IN). Кроме того, меньше критериев для группировки на сумму. –

1

Это делает то, что вы хотите?

SELECT contexts.keyword, neurons.id, neurons.name, SUM(synapses.strength) 
FROM neurons 
INNER JOIN synapses ON neurons.id = synapses.n1_id OR neurons.id = synapses.n2_id 
INNER JOIN contexts ON synapses.context_id = contexts.id 
GROUP BY contexts.keyword, neurons.id, neurons.name 
+0

Я получаю следующую ошибку: # 1064 - У Вас есть ошибка в вашем SQL синтаксиса; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с синапсами INNER JOIN ON neurons.id = synapses.n1_id ИЛИ neurons.id = synapses.n2_i 'в строке 3 – Adam

+0

исправлено? :) Мне просто пришлось удалить некоторые запятые –

+0

Хорошая работа - мне пришлось изменить контекст в контексты в нескольких местах, но он отлично работает. Спасибо, Майк. +1. – Adam

Смежные вопросы