создать представление и объединение двух таблиц запроса - PullRequest
0 голосов
/ 27 февраля 2020

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

Мне нужно создать таблицу представления и объединить 2 таблицы вместе, но мне нужно только отображать записи с пропущенные данные.

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

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

Это то, что я пытался

CREATE VIEW uncommissioned AS
SELECT DISTINCT 
    drone.manufacturer AS manufacture, 
    drone.serial, 
    drone.type, 
    drone.purchase_date, 
    maintenance.type AS maintenance
FROM drone 
INNER JOIN maintenance ON drone.type = maintenance.type
WHERE maintenance.type = 'NULL';

Но это дает пустую таблицу, какие-либо предложения о том, где я иду не так?

Ответы [ 3 ]

1 голос
/ 27 февраля 2020

Я думаю, что вы хотите анти- LEFT JOIN:

CREATE VIEW uncommissioned AS
SELECT DISTINCT 
    d.manufacturer AS manufacture, 
    d.serial, 
    d.type, 
    d.purchase_date, 
    d.type AS maintenance
FROM drone d
LEFT JOIN maintenance m ON d.type = m.type
WHERE m.type IS NULL;

Примечания:

  • для проверки на ничтожность, вам нужна конструкция IS NULL (ваш код проверяет наличие буквальной строки 'NULL'):

  • если вы хотите отобразить тип обслуживания, вам нужно взять эту информацию из таблицы drone, а не из maintenance таблица

Вы также можете сформулировать это с условием NOT EXISTS и коррелированным подзапросом:

CREATE VIEW uncommissioned AS
SELECT DISTINCT 
    d.manufacturer AS manufacture, 
    d.serial, 
    d.type, 
    d.purchase_date, 
    d.type AS maintenance
FROM drone d
WHERE NOT EXISTS (SELECT 1 FROM maintenance m WHERE d.type = m.type)
0 голосов
/ 27 февраля 2020

Исходя из вашего последнего комментария:

Шаг за шагом и создание того, что вы хотите сделать (мы объединим эти наборы позже) ....

  1. Вы хотите проверить все свои дроны. Итак, давайте выберем столбцы из таблицы drones, чтобы посмотреть, что там.

    SELECT * FROM drones ;
    
    manufacturer           | serial | type | purchase_date      
    :--------------------- | -----: | ---: | :------------------
    Lockheed Martin        |      1 |    1 | 2020-01-01 00:00:00
    Aerial Robotic Systems |      2 |   10 | 2020-02-01 00:00:00
    Amazon                 |      3 |  100 | 2020-03-01 00:00:00
    Northrup Grumman       |      4 |    2 | 2020-04-01 00:00:00
    DJI                    |      5 |   20 | 2020-05-01 00:00:00
    Titan Aerospace        |      6 |  200 | 2020-06-01 00:00:00
    
  2. Что находится в таблице maintenance?

    SELECT * FROM maintenance ;
    
    dronetype | mxtype           
    --------: | :----------------
            1 | Replace propeller
            1 | Commissioned     
          100 | Commissioned     
            2 | Commissioned     
           20 | Commissioned     
          200 | DECOMMISSIONED   
    
  3. Как эти две таблицы связаны друг с другом? Давайте подключим их вместе с JOIN на type. MOTE: Я сделал предположение и изменил maintenance.type, чтобы более точно описать, как я думаю, что эти отношения должны быть.

    3.1. Какие JOIN нам нужны? (Для иллюстрации: https://www.edureka.co/blog/sql-joins-types). Я только посмотрю на INNER и OUTER JOIN с.

    3.1.1. INNER JOIN даст нам только записи, которые соответствуют ОБА таблицам.

    SELECT d.manufacturer, d.serial, d.type, d.purchase_date, m.mxtype
    FROM drones d
    INNER JOIN maintenance m ON d.type = m.dronetype ;
    
    manufacturer     | serial | type | purchase_date       | mxtype           
    :--------------- | -----: | ---: | :------------------ | :----------------
    Lockheed Martin  |      1 |    1 | 2020-01-01 00:00:00 | Replace propeller
    Lockheed Martin  |      1 |    1 | 2020-01-01 00:00:00 | Commissioned     
    Amazon           |      3 |  100 | 2020-03-01 00:00:00 | Commissioned     
    Northrup Grumman |      4 |    2 | 2020-04-01 00:00:00 | Commissioned     
    DJI              |      5 |   20 | 2020-05-01 00:00:00 | Commissioned     
    Titan Aerospace  |      6 |  200 | 2020-06-01 00:00:00 | DECOMMISSIONED   
    

    Это не совсем то, что мы хотим.

    3.1.2 OUTER JOIN даст нам записи из одной из таблиц и соответствующие строки в другой таблице. Несопоставленные строки будут NULL.

    SELECT d.manufacturer, d.serial, d.type, d.purchase_date, m.mxtype
    FROM drones d
    LEFT OUTER JOIN maintenance m ON d.type = m.dronetype ;
    
    manufacturer           | serial | type | purchase_date       | mxtype           
    :--------------------- | -----: | ---: | :------------------ | :----------------
    Lockheed Martin        |      1 |    1 | 2020-01-01 00:00:00 | Replace propeller
    Lockheed Martin        |      1 |    1 | 2020-01-01 00:00:00 | Commissioned     
    Amazon                 |      3 |  100 | 2020-03-01 00:00:00 | Commissioned     
    Northrup Grumman       |      4 |    2 | 2020-04-01 00:00:00 | Commissioned     
    DJI                    |      5 |   20 | 2020-05-01 00:00:00 | Commissioned     
    Titan Aerospace        |      6 |  200 | 2020-06-01 00:00:00 | DECOMMISSIONED   
    Aerial Robotic Systems |      2 |   10 | 2020-02-01 00:00:00 | <em>null</em>             
    
    That shows us all of the `drones` with a `NULL` record for the non-matched one.
    
  4. Но мы хотим показать дронов, которые еще не были Commissioned в таблице maintenance.

    SELECT d.manufacturer, d.serial, d.type, d.purchase_date, m.mxtype
    FROM drones d
    LEFT OUTER JOIN maintenance m ON d.type = m.dronetype 
    WHERE m.mxtype <> 'commissioned' ;
    
    manufacturer    | serial | type | purchase_date       | mxtype           
    :-------------- | -----: | ---: | :------------------ | :----------------
    Lockheed Martin |      1 |    1 | 2020-01-01 00:00:00 | Replace propeller
    Titan Aerospace |      6 |  200 | 2020-06-01 00:00:00 | DECOMMISSIONED   
    

    Но теперь мы пропускаем нашу непревзойденную запись и показываем записи, которые нам не нужны (например, запись Lockheed Martin, которая имеет 2 maintenance записей с одним существом Commissioned).

  5. Итак, давайте выберем записи из нашей таблицы drones, которые не имеют запись Commissioned в maintenance. Мы можем сделать это с помощью NOT EXISTS.

    SELECT d.manufacturer, d.serial, d.type, d.purchase_date
    FROM drones d
    WHERE NOT EXISTS (
        SELECT 1 /* This can be anything. It's ignored. */
        FROM maintenance m 
        WHERE m.mxtype = 'commissioned' 
           AND m.dronetype = d.type
     ) ;
    
    manufacturer           | serial | type | purchase_date      
    :--------------------- | -----: | ---: | :------------------
    Aerial Robotic Systems |      2 |   10 | 2020-02-01 00:00:00
    Titan Aerospace        |      6 |  200 | 2020-06-01 00:00:00
    

    Теперь у нас есть два дрона, у которых нет записи в maintenance за то, что они Commissioned.

    ПРИМЕЧАНИЕ. В этом последнем запросе мы использовали коррелированный подзапрос для связи таблицы maintenance с таблицей drones, и мы включили условие в наш запрос для maintenance таблица для выбора только записей с mxtype или commissioned. И WHERE NOT EXISTS отфильтрует запрос таблицы drones, чтобы исключить любые строки, которые имеют совпадение в подзапросе.

Вы можете поиграть с запросом и данные здесь: дБ <> скрипка

0 голосов
/ 27 февраля 2020

IS NULL - это правильно, и RIGHT JOIN, потому что NULL в правом обслуживании таблицы
Попробуйте: SELECT DISTINCT drone.manufacturer AS manufacture, drone.serial, drone.type, drone.purchase_date, maintenance.type AS maintenance FROM drone RIGHT OUTER JOIN maintenance ON drone.type = maintenance.type WHERE maintenance.type IS NULL;

...