Эффективный и поддерживаемый запрос для сравнения производных данных с течением времени - PullRequest
0 голосов
/ 08 июня 2018

У меня есть база данных, содержащая ScanSessions и LapEntries.

CREATE TABLE `ScanningSession` (
     `id` varchar(512) NOT NULL,
     `startDate` datetime NOT NULL)

  CREATE TABLE `LapEntry` (
    `studentId` int(11) NOT NULL,
    `laps` int(11) NOT NULL,
    `scanSessionId` varchar(512) DEFAULT NULL,
    `timestamp` datetime DEFAULT NULL) 

Записи связаны с сеансами по идентификатору сеанса, то есть многие к одному.У меня довольно большой запрос, который выводит данные на нескольких уровнях.Так как он должен вычислять время прохождения круга с начала сеанса, деление круга, общее время и такие вещи, как ординальность (круг 1, круг 2) и общее расстояние после каждого круга, его большая

    select
  `le`.`studentId`,

  ifnull(
      (
        select TIMEDIFF(`le`.`timestamp`, max(`timestamp`))
        from `LapEntry` `le3`
        where `le3`.`studentId` = `le`.`studentId`
              and `le3`.`scanSessionId` = `ss`.`id`
              and `le3`.`timestamp` < `le`.`timestamp`
      ),
      timediff(`le`.`timestamp`, `ss`.`startDate`)
  )                             as `laptime`,
     `studentSessionOverview`.`dist`,
     `studentSessionOverview`.`numLaps`
from `ScanningSession` `ss`
  join `LapEntry` `le`
    on `le`.`scanSessionId` = `ss`.`id`

  join (
         select
           `studentId`,
           max(`timestamp`)    `max_timestamp`,
           count(*)            `numLaps`,
           (sum(`le2`.`laps`) * `c`.`distance` * `cu`.`convertToMiles`) / `su`.`convertToMiles` `dist`
         from `LapEntry` `le2`,
           `Course` `c`,
           `Unit` `cu`,
           `School` `s`,
           `Unit` `su`
         where `c`.`id` = `le2`.`courseId`
               and `cu`.`id` = `c`.`unitId`
               and `s`.`id` = 'school id here'
               and `su`.`id` = `s`.`defaultUnitId`
               and `le2`.`scanSessionId` ='sessionID here' 
         group by `studentId`
       ) as `studentSessionOverview`

    on `studentSessionOverview`.`studentId` = `le`.`studentId`
where `ss`.`id` = 'sessionID here';

Моя проблема фактически начинаетсякогда я пытаюсь сделать сравнение между двумя сеансами сканирования.Пользователи хотят видеть успехи данного ученика между двумя сессиями.

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

   select
  `a`.`firstNAme`,
  `a`.`lastName`,
  `a`.`laptime` - `b`.`laptime`     as `lapDifference`,
  `a`.`totalTime` - `b`.`totalTime` as `totalDifference`
  from (*wall of sql here*) as a
  join (*wall of sql here*) as b 
    on `a`.`studentId` = `b`.`studentId` and `a`.`lapOrder` = 
    `b`.`lapOrder`    

Есть ли способ получить эти данные без жесткого копирования моего запроса?Я не могу понять, как получить все данные, необходимые для каждого сеанса, а затем выполнить сравнение сеансов поверх всего этого.

PS Я действительно рассматривал возможность использования хранимых процедур и запуска процедуры в качестве вызова от родителя.запрос, но это заставляет меня сохранять некоторые SQL в своем API-коде и некоторые на сервере для хранимых процедур, что является такой же серьезной проблемой обслуживания, как и то, чего я пытаюсь избежать.

1 Ответ

0 голосов
/ 18 июня 2018

В моем случае ответом на это стало возвращение к моему API-коду и составление этого запроса в виде строки.

Итак, что-то структурировано так:

string subSql = *The large query with parameters*;
string sql = 'select * from (subSql, parameters for session 1) as A
join (subsql, parameters for session 2) as B 
on a.sessionId = b.sessionId;

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

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