2012-04-13 3 views
0

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

У меня есть таблица следующий формат, подобный следующему:

| id | other_id | timestamp | 
| 1 |  1 | 2012-01-01 | 
| 2 |  1 | 2012-01-02 | 
| 3 |  2 | 2012-01-02 | 

То, что я пытаюсь сделать это, учитывая запись с «ид» 2, и подобные записи, для которых столбец «Идентификатор» значение известно и уникально, и известно, что «other_id» соответствует ему, как мне найти для каждого «id» записи, имеющей тот же «other_id», но первый более низкий «id», чем тот, который я уже знать.

E.g.

$arrKnownIds = array (
0 => array('id'=>2,'other_id'=>1), 
1 => array('id'=>3,'other_id'=>2) 
); 

С этой информацией, я хотел бы выполнить запрос таким образом, что это приводит:

while($row = mysql_fetch_assoc($result)) { 
$arrPreviousIds[$row['other_id']] = $row['id']; 
// having in this case values of: 
// $row['other_id'] = 2; 
// $row['id'] = 1; 
} 

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

Любые мысли о том, как решить эту проблему, очень ценятся.

Спасибо :)

Edit - Исходный запрос имеет следующий вид:

SELECT DISTINCT(`other_id`), MAX(`id`), MAX(`timestamp`) 
FROM `event` 
GROUP BY `other_id` 
ORDER BY `id` DESC, `other_id` ASC 
LIMIT 0, 10 

// Это предназначено, чтобы получить последние 10 уникальных событий и найти, когда они произошли.

// Из этого я затем пытаюсь найти, когда они были ранее.

+0

Я не уверен, что я понимаю, чего вы хотите. Учитывая id 2, он должен возвращать id 1, потому что это самый высокий id менее 2 с other_id = 1. Правильно ли это? Итак, учитывая id 3, если он возвращает null, поскольку нет более низкого id с other_id = 2? – nnichols

+0

@nnichols, Да, это точно так, как вы описали его. – MyStream

ответ

1

Как насчет этого?

SELECT t1.id, (SELECT id 
       FROM tbl t2 
       WHERE t2.other_id = t1.other_id 
       AND t2.id < t1.id 
       ORDER BY t2.id DESC 
       LIMIT 1) 
FROM tbl t1 
WHERE t1.id IN (1,2,3) 

Есть более эффективные способы сделать это, если вы будете иметь дело с большими наборами результатов. Можете ли вы объяснить, как именно вы будете использовать этот запрос?

UPDATE - на основе того существующего запроса на вопрос здесь обновленный запрос, чтобы объединить два -

SELECT tmp.*, (SELECT `timestamp` 
       FROM `event` 
       WHERE `event`.`other_id` = `tmp`.`other_id` 
       AND `event`.`id` < `tmp`.`id` 
       ORDER BY `event`.`id` DESC 
       LIMIT 1) AS `prev_timestamp` 
FROM (
    SELECT `other_id`, MAX(`id`) AS `id`, MAX(`timestamp`) AS `timestamp` 
    FROM `event` 
    GROUP BY `other_id` 
    ORDER BY `id` DESC, `other_id` ASC 
    LIMIT 0, 10 
) tmp 

Я не пробовал это, но это должно дать желаемый результат.

+0

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

+0

В этом случае результирующий набор имеет порядок 10-100, но набор данных для поиска имеет порядок 10 М, поэтому я не хотел ударять базу данных 100 раз в худшем случае (или 10 для этого материи), но синтаксис IN отлично справляется в этой ситуации. – MyStream

+0

Это должно работать для вас тогда, но вы должны иметь возможность получить весь результат в одном запросе. Может быть, вы должны добавить свой существующий запрос к своему вопросу. Из того, что вы сказали, я предполагаю, что вы запустили один запрос, а затем передали идентификаторы из этого в этот запрос. Если это так, то это, безусловно, может быть объединено в один запрос. – nnichols

Смежные вопросы