Нахождение среднего рейтинга бронирования от каждого водителя за месяц в SQL - PullRequest
0 голосов
/ 14 июня 2019

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

Мне нужно перечислить все имена водителей, их возраст, должность и их средний рейтинг за определенный месяц.Перечисление имени, возраста и положения в порядке, но у меня проблема со средним рейтингом (так как для «бронирования» мало записей, нужно рассчитать среднее из этих записей), а также сгруппировать их по каждому водителю за определенный месяц

ниже приведены мои коды

  table booking
  BookID NUMBER(4) PRIMARY KEY,
  PersonID NUMBER(4),
  driverID NUMBER(4),    
  PickLoc VARCHAR2(13),
  DropLoc VARCHAR2(13),
  TDate DATE,
  TTime NUMBER(4),
  RideFare CHAR(6),
  TollOther CHAR(6),
  cancelDate DATE,
  TripRating NUMBER(1), 
  PayMethod CHAR(15),



  table driver
  driverID NUMBER(4) PRIMARY KEY, 
  Dname VARCHAR2(20),
  DNRIC CHAR(14),
  Dgender CHAR(1),
  DDOB DATE,
  Dmobile CHAR(11),
  DcarNo CHAR(6),
  Dstart DATE,
  Dgrade CHAR(6),
  DLicence CHAR(4),
  );

Ответы [ 3 ]

1 голос
/ 14 июня 2019

Это простая группа по и применяется функция avg (средняя).

select Dname, timestampdiff(year,Ddob,Now()) as age, 
       Dgrade, avg(TripRating) as rate
from booking
     inner join driver on driver.driverID = booking.driverID
where extract(year from TDate) = 2019 and
      extract(month from TDate) = 1
group by Dname, timestampdiff(year,Ddob,Now()), Dgrade

Он вернет ваши средние значения за январь 2019

PS: Поскольку @RohanKumar предупредил меня, мой ответ не даст никакого результата для водителей без бронирования на этот период. Если вы хотите, чтобы в наборе результатов были все драйверы, даже те, которые не были зарезервированы, мы изменим порядок объединения, используя драйвер в качестве основной таблицы и изменив соединение для внешнего соединения, поэтому мы возвращаем драйверы без резервирований.

select Dname, timestampdiff(year,Ddob,Now()) as age, 
       Dgrade, avg(TripRating) as rate
from driver
     left join booking on booking.driverID = driver.driverID
where extract(year from TDate) = 2019 and
      extract(month from TDate) = 1
group by Dname, timestampdiff(year,Ddob,Now()), Dgrade
0 голосов
/ 14 июня 2019

сначала вы должны присоединиться к своим таблицам и выбрать столбцы, необходимые для ваших расчетов:

SELECT Dname, Triprating, DDOB, TDate 
FROM  driver, booking 
WHERE booking.driverID = driver.driverID;

возраст водителей немного сложен. В соответствии с https://stackoverflow.com/a/23824981/2331592 это может выглядеть так (при условии, что вы хотите указать возраст на момент бронирования)

TIMESTAMPDIFF(YEAR, TDate , DDOB)

также месяцы бронирования: я бы посоветовал также принять во внимание год, возможно, преобразовав его в '2019-06' на

DATE_FORMAT(TDate ,'%Y-%m')

поэтому запрос теперь будет выглядеть как

SELECT Dname, TIMESTAMPDIFF(YEAR, TDate , DDOB) AS Dage, DATE_FORMAT(TDate ,'%Y-%m') AS Tmonth,  Triprating 
FROM  driver, booking 
WHERE booking.driverID = driver.driverID;

Теперь это таблица со всей информацией, и мы хотим сгруппировать некоторые вещи.
Для этого нам нужны агрегатные функции для полей, которые мы не хотим группировать.

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

SELECT  Dname as driver, 
        MAX(Dage) as age, 
        Tmonth as month, 
        AVG(Triprating) as 'average rating'
FROM    (SELECT Dname, 
                TIMESTAMPDIFF(YEAR, TDate , DDOB) AS Dage, 
                DATE_FORMAT(TDate ,"%Y-%m") AS Tmonth,  
                Triprating 
         FROM   driver, booking 
         WHERE  booking.driverID = driver.driverID
        )
GROUP BY driver, month
ORDER BY driver ASC, month ASC;

с легкой адаптацией к SQLite вышеуказанный SQL работает и может быть опробован на: https://sqliteonline.com/#fiddle-5d04d5f898b5cmzxjwxfrdws

Edit:

, как предполагает Рохан Кумар в своем ответе, группирование данных бронирования может быть выполнено до объединения. это уменьшит количество строк для объединения и может быть немного быстрее и потреблять меньше ресурсов. Но в этом варианте возраст водителя во время бронирования не может быть рассчитан так просто.

0 голосов
/ 14 июня 2019

Это совсем не сложно! Вам просто нужно объединить таблицы, сгруппировать по идентификатору драйвера, а затем просто использовать метод функции AVG ()!

SQL:

SELECT Dname as driver, 
       TIMESTAMPDIFF(YEAR, DDOB, CUR_DATE()) as age,
       Dgrade as position,
       rating
FROM driver 
LEFT JOIN 
(SELECT driverID, AVG(TripRating) as rating
 FROM booking group by driverID, MONTH(TDate)
) booking
on driver.driverID = booking.driverID

При этом будут перечислены все рейтинги водителей за все месяцы, для любого данного месяца просто измените внутренний SQL таблицы бронирования.

Это изменение будет таким же для января (месяц 1):

SELECT driverID, avg(TripRating) as rating
 FROM booking group by driverID
where MONTH(TDate) = 1

полезные ссылки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...