#mysql #sql
#mysql #sql
Вопрос:
Это моя структура таблицы sql:
Таблица 1: подробности
|--id--|--id_user--|--price--|
| 1 | 1 | 10 |
| 2 | 2 | 15 |
| 3 | 1 | 25 |
| 4 | 3 | 30 |
| 5 | 3 | 7 |
------------------------------
Таблица 2: пользователи
|--id--|--id_country--|
| 1 | 1 |
| 2 | 2 |
| 3 | 0 |
-----------------------
Таблица 3: страна
|--id--|--country--|
| 1 | France |
| 2 | Italy |
--------------------
Что мне нужно, так это получить СУММУ цен по странам:
SELECT c.country, SUM(d.price) AS price
FROM details d
INNER JOIN users u ON u.id = d.id_user
INNER JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
Я понимаю это:
|--country--|--price--|
| France | 35 |
| Italy | 15 |
-----------------------
НО мне нужно было бы получить это:
|--country--|--price--|
| France | 35 |
| Italy | 15 |
| Undefined | 37 |
-----------------------
где undefined
было бы, если id_country=0
. (Я не могу добавить в таблицу country id=0 or id=undefined
, это испортит другие вещи). Прямо сейчас я добиваюсь этого с помощью двух отдельных запросов, второй:
SELECT SUM(d.price) as price
FROM details d
INNER JOIN users u ON u.id = d.id_user AND u.id_country=0
GROUP BY u.id_country
Я думаю, если … возможно ли это сделать в одном запросе?
Комментарии:
1. Переключитесь на LEFT JOIN Country.
2. ПРАВОЕ СОЕДИНЕНИЕ
INNER JOIN country c
3. Странно видеть, что вы можете использовать id_country в своей таблице users, которая не существует. Это показывает, что вы неправильно используете свою базу данных. У вас должно быть ограничение внешнего ключа и сделать столбец обнуляемым, если вы хотите разрешить «неопределенную страну».
4. @Thorsten-Kettner можете ли вы написать, ссылаясь на приведенный выше пример, как мне правильно это построить?
5. Обычно вы создаете таблицы с внешними ключами. Итак, вы
Country
сначала создаете таблицу сid
первичным ключом, а затем создаете таблицуusers
сusers.id_country
внешним ключомcountry.id
. Но вы также можете добавить это позже сalter table
помощью . Читайте здесь: mysqltutorial.org/mysql-foreign-key
Ответ №1:
В этом случае вам нужно использовать левое соединение:
SELECT c.country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
Если вы используете ВНУТРЕННЕЕ СОЕДИНЕНИЕ, вы получите только те результаты, которые существуют в обеих таблицах.
Для замены NULL на Undefined используйте:
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
Один из способов сортировки, чтобы получить Undefined last, — добавить поле сортировки
SELECT A.Country,A.Price FROM (
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price, IFNULL(c.Country,'ZZZZZZZZ') AS Sort
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
) A
ORDER BY A.Sort
Редактировать: ПОРЯДОК ПО предложенному в комментариях
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country IS NULL, c.country
Комментарии:
1. ваше право, можно ли изменить «null» на «undefined» или другое слово и вставить в начало или конец результирующей таблицы?
2. Чтобы получить нули в конце, используйте:
ORDER BY c.country IS NULL, c.country
.3. Мне нравится этот средний ответ, начинающийся с
SELECT IFNULL
, но в конце используйте предложение от @Thorsten-KettnerORDER BY c.country IS NULL, c.country
и отлично работает! Спасибо за ответы.
Ответ №2:
Попробуйте выполнить запрос ниже.
SELECT
CASE
WHEN c.country is NULL THEN 'Undefined'
ELSE c.country
END as country
, SUM(d.price) AS price
FROM users u
left JOIN details d ON u.id = d.id_user
left JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
Для демонстрации :
Пожалуйста, дайте нам знать, если у вас есть какие-либо вопросы.