MySQL присоединиться к лучшему варианту здесь?

#mysql #sql

#mysql #sql

Вопрос:

кампании:

 id     name            cap
1      Campaign1       2
2      Campaign2       1
3      Campaign3       1
  

обслуживается:

 id     id_campaign     ip
1      1               127.0.0.1
2      1               127.0.0.1
3      2               127.0.0.1
  

Результат запроса должен отображать:

 campaigns_id    campaigns_name          cap    count
1               Campaign1               2      2
2               Campaign2               1      1
3               Campaign3               1      0
  

Я использую этот запрос:

    SELECT served.id_campaign, 
          campaigns.name, 
          campaigns.cap, 
          COUNT( served.id ) AS count
     FROM campaigns
LEFT JOIN served ON campaigns.id = served.id_campaign
    WHERE served.ip =  '127.0.0.1' 
 GROUP BY served.id_campaign
  

Мой запрос отображает эти результаты (плохой, не показывает campaigns_id.3):

 campaigns_id    campaigns_name          cap    count
1               Campaign1               2      2
2               Campaign2               1      1
  

Я думаю, что я ошибаюсь, если хочу включить значения, которые не выбираются с помощью инструкции «WHERE», поскольку в «served» нет записей, которые соответствуют инструкции WHERE для campaigns.id =’3′

Ответ №1:

НОВАЯ ПРАВКА:

    SELECT campaigns.id as id_campaign, 
          campaigns.name, 
          campaigns.cap, 
          COUNT( served.id ) AS count
     FROM campaigns
LEFT JOIN served ON campaigns.id = served.id_campaign
      AND served.ip =  '127.0.0.1' 
 GROUP BY campaigns.id
  

СТАРЫЙ ПОСТ:

Я придумал этот запрос, который выдает желаемый результат:

 (SELECT served.id_campaign, 
          campaigns.name, 
          campaigns.cap, 
          COUNT( served.id ) AS count
     FROM campaigns
LEFT JOIN served ON campaigns.id = served.id_campaign
    WHERE served.ip =  '127.0.0.1' 
 GROUP BY served.id_campaign)

UNION

(SELECT id, name, cap, 0 as count 
FROM campaigns 
WHERE id <> ALL 
     (
      SELECT campaigns.id 
      FROM campaigns, served 
      WHERE campaigns.id = served.id_campaign AND served.ip = "127.0.0.1"
     )
)
  

Комментарии:

1. Это сработало, но загрузка запроса заняла 26 секунд. «обслуживаемый» содержит более 300 000 строк. Возможно, есть способ выполнить запрос без необходимости запрашивать через «served» дважды.

2. Я отредактировал сообщение с помощью нового запроса. Это только что исправленный запрос от Andriy M. Я думаю, что это должно сработать, и он запрашивает таблицу, «обслуживаемую» только один раз. Наслаждайтесь!

3. Я думаю, что это хорошая идея заменить served.id_campaign на campaigns.id в списке ВЫБОРА. Похоже, что ваш новый запрос теперь требует только одного исправления: предложение GROUP BY, вероятно, должно быть GROUP BY campaigns.id . (ОБНОВЛЕНИЕ: я взял на себя смелость соответствующим образом отредактировать ваш пост. Если вы не согласны, пожалуйста, не стесняйтесь отменить изменение.)

Ответ №2:

Измените ваше предложение where на

 WHERE served.ip =  '127.0.0.1' OR served.ip IS NULL
  

Комментарии:

1. Не могу этого сделать, потому что мне нужно выбрать записи из «served», которые соответствуют определенному IP. Выполнение этого, по сути, означает выполнение инструкции WHERE 1 = 1.

2. Нет, это не так. По сути, это говорит о том, что показывать только записи, если serverip равен ‘127.0.0.1’ или IP-адрес сервера не установлен. Это исключит все другие IP-адреса.

3. Я понимаю, о чем вы говорите. Я неправильно истолковал ответ. Это не сработает, потому что для served.ip всегда есть значение, а отсутствующая строка из «campaigns» отсутствует, потому что в «served» нет связанной строки.

Ответ №3:

ЛЕВОЕ СОЕДИНЕНИЕ говорит, что переносит все записи из левой таблицы и соответствующие записи из правой боковой таблицы. Таким образом, обслуживаемый.ip будет равен НУЛЮ с id = 3. Поэтому измените условие where, чтобы оно

 WHERE serverd.ip = '127.0.0.1' or serverd.ip IS NULL
  

Комментарии:

1. Как вы можете видеть из вывода, который я хочу (вывод ниже «Результат запроса должен отображаться») Я хочу включить результат для идентификатора 3. LEFT JOIN и JOIN возвращают здесь те же результаты.

2. ооо, извините, я просто пропустил это. Попробуйте это served.ip = ‘127.0.0.1’ или served.ip равно НУЛЮ . Причина, по которой это сработает, заключается в том, что обслуживаемый.ip в результирующем наборе будет либо пустым, либо нулевым. Надеюсь, это поможет.