sql запрос объединить два запроса в один с пустыми строками

#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-Kettner ORDER 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
  

Для демонстрации :

Демонстрация SQLFiddle :

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