«Простой» SQL-запрос - PullRequest
       5

«Простой» SQL-запрос

2 голосов
/ 29 октября 2008

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

Каким будет запрос для обнаружения следующего отмененного элемента todo к дате исполнения для каждого файла? В случае, если у клиента более одной задачи, правильной будет та, которая имеет наименьший идентификатор.

Предполагая следующую минимальную схему:

clients (id, name)

todos (id, client_id, description, timestamp_due, timestamp_completed)

Спасибо.

Ответы [ 5 ]

3 голосов
/ 29 октября 2008

Я еще не проверял это, поэтому вам, возможно, придется настроить его:

SELECT
    TD1.client_id,
    TD1.id,
    TD1.description,
    TD1.timestamp_due
FROM
    Todos TD1
LEFT OUTER JOIN Todos TD2 ON
    TD2.client_id = TD1.client_id AND
    TD2.timestamp_completed IS NULL AND
    (
        TD2.timestamp_due < TD1.timestamp_due OR
        (TD2.timestamp_due = TD1.timestamp_due AND TD2.id < TD1.id)
    )
WHERE
    TD2.id IS NULL

Вместо того, чтобы пытаться сортировать и агрегировать, вы в основном отвечаете на вопрос: "Есть ли еще какие-нибудь задачи, которые могут возникнуть до этого?" (на основе вашего определения «до»). Если нет, то это тот, который вы хотите.

Это должно быть допустимо на большинстве платформ SQL.

3 голосов
/ 29 октября 2008

Этот вопрос является классическим победителем в каждой группе . Он публикуется примерно два раза в день.

SELECT *
FROM todos t
WHERE t.timestamp_completed is null
  and
(
  SELECT top 1 t2.id
  FROM todos t2
  WHERE t.client_id = t2.client_id
    and t2.timestamp_completed is null
     --there is no earlier record
    and
    (t.timestamp_due > t2.timestamp_due
       or (t.timestamp_due = t2.timestamp_due and t.id > t2.id)
    )
) is null
2 голосов
/ 29 октября 2008
SELECT c.name, MIN(t.id)
FROM clients c, todos t
WHERE c.id = t.client_id AND t.timestamp_complete IS NULL
GROUP BY c.id
HAVING t.timestamp_due <= MIN(t.timestamp_due)

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

0 голосов
/ 29 октября 2008

Какой-то Jet SQL, я понимаю, что маловероятно, что спрашивающий использует Jet, однако читатель может быть.

SELECT c.name, t.description, t.timestamp_due
FROM (clients c 
      INNER JOIN 
         (SELECT t.client_id, Min(t.id) AS MinOfid
          FROM todos t
          WHERE t.timestamp_completed Is Null
          GROUP BY t.client_id) AS tm 
ON c.id = tm.client_id) 
INNER JOIN todos t ON tm.MinOfid = t.id
0 голосов
/ 29 октября 2008

Следующее должно приблизить вас, сначала получите минимальное время для каждого клиента, затем найдите информацию о клиенте / задачах

SELECT
    C.Id,
    C.Name,
    T.Id
    T.Description,
    T.timestamp_due
FROM
{
    SELECT
        client_id,
        MIN(timestamp_due) AS "DueDate"
    FROM todos
    WHERE timestamp_completed IS NULL
    GROUP BY ClientId
} AS MinValues
    INNER JOIN Clients C
    ON (MinValues.client_id = C.Id)
    INNER JOIN todos T
    ON (MinValues.client_id = T.client_id
        AND MinValues.DueDate = T.timestamp_due)
ORDER BY C.Name

ПРИМЕЧАНИЕ: Написано с учетом SQL Server

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