Проблема с запросом MYSQL при слиянии

Привет, у меня есть запрос MYSQL, как показано ниже:

SELECT COUNT(od.id)+IFNULL((SELECT COUNT(rmrs.id)
FROM ic_dd_results rmrs
WHERE rmd.horse_id = od.horse_mraid AND rmrs.finish_pos = '1'),0) as count_win
FROM ic_dd_old_data od
WHERE od.horse_mraid = '123123' AND od.pl='1'

Запрос вернет правильные данные, если первый запрос count_win соответствует finish_pos =1, но когда второй запрос не содержит данных для pl='1', он проигнорирует первый запрос. Я хочу, чтобы общий результат запроса был возвращен путем объединения 1-го и 2-го.

Какой у Вас вопрос?

Peter Abolins 18.04.2018 10:20

Пожалуйста, предоставьте структуру таблицы, образец данных и желаемый результат. Также не забудьте прояснить свой вопрос.

Paul Karam 18.04.2018 10:24

Ваш запрос недействителен (согласно стандарту SQL). Вы выбираете записи ic_dd_old_data, каждая вместе со счетчиком ic_dd_results. Затем вы подсчитываете все эти строки и к этому счету добавляете какие? Помните, что вы сгенерировали несколько счетчиков ic_dd_results, но вдруг вы относитесь к этому так, как если бы это было одно единственное значение, которое вы могли бы добавить к счетчику строк. MySQL допускает это и произвольно выбирает для вас один счетчик ic_dd_results. (Вы можете сделать это явным, написав ANY_VALUE(IFNULL((SELECT COUNT(rmrs.id) ...).) Подумайте, что вы действительно хотите добавить или посчитать.

Thorsten Kettner 18.04.2018 10:33

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

GTS85 18.04.2018 11:40

Благодарим всех за помощь и приму к сведению в будущем.

GTS85 18.04.2018 11:41
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
5
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, вы также можете сделать это с помощью условного агрегирование вместо фильтрации pl=1 в предложении where

SELECT COUNT(CASE WHEN od.pl='1' THEN od.id END) + 
       IFNULL((SELECT COUNT(rmrs.id)
               FROM ic_dd_results rmrs
               WHERE rmd.horse_id = od.horse_mraid AND 
               rmrs.finish_pos = '1'),0) as count_win
FROM ic_dd_old_data od
WHERE od.horse_mraid = '123123' 

спасибо за ваш быстрый код, и он отлично работает! Я так ценю.

GTS85 18.04.2018 11:39

Однако это не лучший запрос. Это работает только потому, что все строки в промежуточном результате имеют один и тот же count_win, одна из которых выбирается произвольно.

Thorsten Kettner 18.04.2018 11:50
Ответ принят как подходящий

Кажется, вы просто ищете

select 
  (select count(*) from ic_dd_old_data where horse_mraid = 123123 and pl = 1) +  
  (select count(*) from ic_dd_results where horse_id = 123123 and finish_pos = 1);

Я тоже так думал.

Yogesh Sharma 18.04.2018 11:57

Возможно, оба будут работать, если разделить счетчик. Полный код приведен ниже: Я пропустил внутреннюю часть соединения, чтобы просто запутать запрос все в 1. <code> SELECT COUNT (CASE WHEN od.pl = '1' THEN od.id END) + IFNULL ((SELECT COUNT (rmrs.id) FROM ic_dd_results rmrs ВНУТРЕННЕЕ СОЕДИНЕНИЕ ic_dd_race rmr ON rmr.track_id = rmrs.track_id И rmr.post_id = rmrs.post_id ВНУТРЕННЕЕ СОЕДИНЕНИЕ ic_dd_declaration rmd ON WH rmd.race_id И rmr. .horse_id = od.horse_mraid И rmrs.finish_pos = '1'), 0) как count_win ОТ ic_dd_old_data od WHERE od.horse_mraid = '". $ horse_mra."'

GTS85 18.04.2018 12:27

Это аналогично ответу Йогеша Шармы. Неверный SQL, который - при условии, что MySQL не находится в режиме ONLY_FULL_GROUP_BY - разрешает MySQL, произвольно выбирая один count_win из всех равных count_win в промежуточном результате. Я знаю, что ваш запрос работает, но вы должны знать, что этот запрос действительно делает, и вам следует научиться писать правильный запрос. COUNT, кстати, всегда возвращает число, а не ноль; так что IFNULL в вашем запросе лишний.

Thorsten Kettner 18.04.2018 13:11

Привет, @ThorstenKettner, спасибо за подробное объяснение. То есть вы имеете в виду, что с точки зрения производительности лучше использовать ниже? select (select count(*) from ic_dd_old_data where horse_mraid = 123123 and pl = 1) + (select count(*) from ic_dd_results where horse_id = 123123 and finish_pos = 1);

GTS85 18.04.2018 14:00

Да, этот запрос соответствует стандарту и должен выполняться как можно быстрее. В конце концов, это просто сумма из одной таблицы плюс сумма из другой, которую вы хотите. Не нужно присоединяться. Если вы хотите, чтобы это было для более чем одного идентификатора лошади, с одной строкой на идентификатор, вы бы присоединились. Но вы бы присоединились к подзапросам ...

Thorsten Kettner 18.04.2018 14:23

... (т.е. select horse_id, coalesce(o.cnt,0) + coalesce(r.cnt,0) as total from (select horse_mraid as horse_id, count(*) as cnt from ic_dd_old_data where pl = 1 group by horse_mraid) o full outer join (select horse_id, count(*) as cnt from ic_dd_results where finish_pos = 1 group by horse_id) using (horse_id) r для СУБД с полными внешними соединениями).

Thorsten Kettner 18.04.2018 14:24

Большое спасибо @ThorstenKettner, узнаем подробнее.

GTS85 19.04.2018 05:48

Другие вопросы по теме