Нужен ли здесь вложенный запрос? - PullRequest
0 голосов
/ 22 июня 2011

Допустим, у меня есть таблица, в которой хранятся результаты гонки. Каждый день несколько машин гоняют по трассе, и я записываю позиции. (Это грубое упрощение, но оно помогает понять смысл)

Таблица выглядит так:

|Driver | Position | Date
 Andy     1          22/06/2011
 Paul     2          22/06/2011
 Cliff    3          22/06/2011
 Andy     2          21/06/2011
 Paul     1          21/06/2011
 Cliff    3          21/06/2011

И так далее ...

Я хотел бы написать запрос, который возвращает позиции водителя на заданную дату, а также позиции за предыдущий день. Я хотел бы для этого вернуть следующие столбцы:

|Driver | Position | Date       | Position Yesterday
 Andy     1          22/06/2011   2
 Paul     2          22/06/2011   1
 Cliff    3          22/06/2011   3

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

Ответы [ 8 ]

4 голосов
/ 22 июня 2011

Вы можете сделать левое присоединение следующим образом:

select
  r1.driver,
  r1.position,
  r1.date
  r2.position as prev_pos
from
  results r1
left join
  results r2 on r1.driver = r2.driver and r2.date = r1 - INTERVAL 1 DAY;
4 голосов
/ 22 июня 2011
SELECT
  [today].*,
  [yesterday].Position
FROM
  yourTable AS [today]
LEFT JOIN
  yourTable AS [yesterday]
    ON  [today].Driver = [yesterday].Driver
    AND [today].Date   = [yesterday].Date + 1
WHERE
  [today].Date = '22/06/2011'
2 голосов
/ 22 июня 2011

Вложенность, кажется, работает лучше (спасибо @Dems за его комментарии) Самостоятельно присоединяюсь к таблице, фильтруя даты. Использование и индексирование (водитель, дата) комбинации

SELECT t1.Driver,t1.Position, t1.Date, t2.Position
FROM table t1
LEFT JOIN (SELECT Driver, Position FROM table ON t1.Driver = t2.Driver AND t2.date ='21/06/2001') ON t1.Driver = t2.Driver
WHERE t1.date = '22/06/2011' 
1 голос
/ 22 июня 2011

Если вы используете MS SQL Server 2008, взгляните на Распространенные табличные выражения

0 голосов
/ 22 июня 2011

Просто еще один вариант:

@givendate = '22/06/2011'

SELECT t1.Driver
     , t1.Position
     , t1.Date
     , ( SELECT t2.Position
         FROM table t2
         WHERE t2.Driver = t1.Driver
           AND t2.date = DATEADD(day, @givendate, -1)
       ) AS PositionYesterday
FROM table t1
WHERE t1.date = @givendate 
0 голосов
/ 22 июня 2011

Я не могу тестировать SQL-запросы прямо здесь, но вот некоторый псевдо-SQL-код, который может работать, если перевести на правильный SQL:

SELECT
  today.driver,
  today.position,
  today.date,
  yesterday.position
FROM
  your_table today,
  ( SELECT driver, position, ( date - 1 day ) "date" FROM your_table ) yesterday
WHERE
  today.driver = yesterday.driver AND
  today.date = yesterday.date

Это, конечно, не компилируется, и я не 100% уверен насчет предложения where.Возможно, вам придется сделать некоторые левые / правые внешние соединения.Кроме того, у вас будут проблемы, когда последняя гонка была не вчера, а накануне.

Надеюсь, это все равно поможет.

0 голосов
/ 22 июня 2011

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

0 голосов
/ 22 июня 2011

Вы можете использовать UNION, один запрос для первых результатов Результаты UNION для второго запроса. Это должно вернуть это правильный путь:

ВЫБРАТЬ * ОТ * ГДЕ =

UNION

ВЫБРАТЬ * ОТ * ГДЕ =

Заполните * s для ваших нужд.

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