Получить минимальное значение из четырех связанных таблиц в SQL - PullRequest
0 голосов
/ 24 апреля 2019

есть пара вопросов, которые у меня есть,

во-первых, когда я читаю некоторые статьи и знаю, что я реализую код SQL с использованием inner Join в этом вопросе. У меня ниже Таблицы :

Больничный стол:

    id  |  hospital_name | adress  | city_id
   -------------------------------------------
    1   | pars           |   55,6LA|   2
    2   | ghaem          |   12.9GI|   2
    3   | Mehr           |   632.Sp|   2
    4   | Erfan          |   21,6UJ|   3
    5   | Razavi         |   31.jjI|   3
    6   | Mohab          |   65.Spi|   1

Таблица городов:

    id  |  cityname 
   --------------------
    1   | LosAngels
    2   | NewYork
    3   | Colifornia

Таблица процедур:

    id  |  TreatmentName 
   ----------------------
    1   | nose surgery   
    2   | Orthopedic  
    3   | Knee joint replacement

treatment_prices Таблица:

    id  |  Treatments_id | Hospital_id  | Price
   ------------------------------------------
    1   |       1        |       1      |   700
    2   |       1        |       6      |   800
    3   |       1        |       4      |   900
    4   |       2        |       1      |   500
    5   |       2        |       2      |   700
    6   |       2        |       3      |   300
    7   |       3        |       1      |   600
    7   |       3        |       2      |   450

мой вопрос - как найти минимальную стоимость лечения в каждой больнице по коду города.

Мне нужно что-то похожее на приведенное ниже. Таблица * Если код города равен 2 :

    price  |  hospital_name | treatment_name| 
   -------------------------------------------
    700    | pars           |   nose surgery   
    300    | Mehr           |   Orthopedic     
    450    | ghaem          |   Knee joint replacement     

это мой SQL код:

SELECT Min(treatment_prices.dollar) AS price, 
       hospitals.name_en            AS hname, 
       treatments.title_en          AS title 
FROM   treatment_prices 
       INNER JOIN hospitals 
               ON hospitals.id = treatment_prices.hospital_id 
       INNER JOIN treatments 
               ON treatments.id = treatment_prices.treatment_id 
WHERE  hospitals.city_id = 2 
GROUP  BY treatment_prices.treatment_id 

* Но это не работает хорошо. Лайк ниже фото: Result of my SQL code

любая помощь будет оценена. *

Ответы [ 3 ]

1 голос
/ 25 апреля 2019

Вы хотите узнать, какая процедура дешевле в какой больнице в городе.

В MySQL 5.x вам придется использовать несколько внутренних подзапросов, чтобы найти самую дешевую процедуру по больницам, а затем снова присоединить ее к своим таблицам, чтобы получить необходимые данные.

См. Скрипту для настройки.

SQL Fiddle

MySQL 5.x :

Во-первых, вы хотите найти самую дешевую цену за процедуру с фильтрацией по вашему городу и больницам в этом городе.

Запрос 1 :

SELECT tp.Treatments_ID, min(tp.Price) AS price
FROM treatment_prices tp
INNER JOIN Hospital h ON tp.Hospital_ID = h.ID
  INNER JOIN Cities c ON h.city_id = c.id
    AND c.ID = 2
GROUP BY tp.Treatments_ID 

Это дает вам

Результаты

| Treatments_ID | price |
|---------------|-------|
|             1 |   700 |
|             2 |   300 |
|             3 |   450 |

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

Запрос 2 :

SELECT t2.TreatmentName, h2.Hospital_Name, s1.Price
FROM (
    SELECT tp.Treatments_ID, min(tp.Price) AS price
    FROM treatment_prices tp
    INNER JOIN Hospital h ON tp.Hospital_ID = h.ID
      INNER JOIN Cities c ON h.city_id = c.id
        AND c.ID = 2
    GROUP BY tp.Treatments_ID 
) s1
INNER JOIN treatment_prices tp2 ON s1.Treatments_ID = tp2.Treatments_ID
    AND s1.price = tp2.Price
INNER JOIN Hospital h2 ON tp2.Hospital_ID = h2.ID
INNER JOIN Treatments t2 ON tp2.Treatments_ID = t2.ID

Результаты

|          TreatmentName | Hospital_Name | Price |
|------------------------|---------------|-------|
|           nose surgery |          pars |   700 |
|             Orthopedic |          Mehr |   300 |
| Knee joint replacement |         ghaem |   450 |

Гораздо проще в более поздних версиях MySQL или любого другого языка SQL, который допускает оконные функции.

MySQL 8 + :

SELECT s1.TreatmentName, s1.Hospital_Name, s1.Price
FROM (
    SELECT t.TreatmentName, h.Hospital_Name, tp.Price
        , ROW_NUMBER() OVER (PARTITION BY tp.Treatments_ID ORDER BY tp.Price) AS rn
    FROM treatment_prices tp 
    INNER JOIN Hospital h ON tp.Hospital_ID = h.ID
    INNER JOIN Cities c ON h.city_id = c.id
            AND c.ID = 2
    INNER JOIN Treatments t ON tp.Treatments_ID = t.ID
) s1
WHERE rn = 1
;

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=9b28f7543c3b127990654ad9e401c11a

0 голосов
/ 25 апреля 2019

Это показывает, что больница должна, потому что у вас есть только GROUP BY treatment_id, когда вы выбираете столбец с функцией агрегации и не включаете его в группу, СУБД распространит результат для этого столбца.из первого ряда во все строки, которые он выбирает.Поэтому сначала сгруппируйте по treatment_id, а затем по hospital_name (или id), и это должно быть сделано.Оставив запрос следующим образом:

   SELECT Min(tp.dollar) AS price, 
          h.name_en      AS hname, 
          t.title_en     AS title 
    FROM   treatment_prices AS tp
           INNER JOIN hospitals AS h
                   ON h.id = tp.hospital_id 
           INNER JOIN treatments AS t 
                   ON t.id = tp.treatment_id 
    WHERE  h.city_id = 2 
    GROUP  BY tp.treatment_id, hname

Обратите внимание, что я использую псевдоним для h.name_en в GROUP BY, MySQL 8+ не имеет проблем с этим, и он использует псевдонимы для более чемвизуальные эффекты.

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

0 голосов
/ 24 апреля 2019

Вы должны использовать GROUP BY hospitals.name_en, treatment.title_en

SELECT Min(treatment_prices.dollar) AS price, 
       hospitals.name_en            AS hname, 
       treatments.title_en          AS title
FROM   treatment_prices 
       INNER JOIN hospitals 
               ON hospitals.id = treatment_prices.hospital_id 
       INNER JOIN treatments 
               ON treatments.id = treatment_prices.treatment_id 
WHERE  hospitals.city_id = 2 
GROUP  BY hospitals.name_en  ,  treatments.title_en     

и для получения больницы с минимальной (цена) должна быть

select  t.price, t.title, hospitals.name_en   

from (
  SELECT Min(treatment_prices.dollar) AS price, 
         treatments.title_en          AS title,
         treatment_prices.treatment_id 
  FROM   treatment_prices 
         INNER JOIN hospitals 
                 ON hospitals.id = treatment_prices.hospital_id 
         INNER JOIN treatments 
                 ON treatments.id = treatment_prices.treatment_id 
  WHERE  hospitals.city_id = 2 
  GROUP  BY  treatments.title_en, treatment_prices.treatment_id
) t 
INNER JOIN treatments ON treatments.id = treatment_prices.treatment_id  
    AND treatments.title_en   = t.title 
INNER JOIN hospitals  ON hospitals.id = treatment_prices.hospital_id   
    AND treatment_prices.dollar = t.price     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...