2012-09-03 3 views
1

Я хочу получить 2 строковых идентификатора перед строками с указанным значением.Выберите строки перед несколькими идентификаторами

Поэтому у меня есть идентификаторы и значения в таблице

ID value 
1, x 
3, x 
7, x 
8, error 
9, x 
10. x 
11, x 
12 error 

Я хочу, чтобы две строки перед ошибками.

я могу сделать это с помощью закодированных идентификаторов строк ошибки

SELECT id FROM thetable WHERE id < 8 ORDER BY ID DESC LIMIT 2 
UNION ALL 
SELECT id FROM thetable WHERE id < 12 ORDER BY ID DESC LIMIT 2 

Howewer Я не могу жёстко идентификатор ошибки, то как я могу это сделать, например, с совместить это с SELECT id FROM thetable WHERE value = 'error' или любым другим способом?

Я использую sqlite 3, но меня интересует все.

+2

Были ни один из ответов на ваши предыдущие семь вопросов приемлемым? – Jodrell

+0

Я написал: это sqlite3 –

+0

Извините, я забыл принять ответы (или не знал, что я должен это сделать). Я делаю это сейчас! Спасибо! –

ответ

3

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

select id,value 
from (select *,rowid rid from tbl 
order by id) 
where rid in 
(
    select rowid-1 from tbl 
    where value = 'error' 
    order by id 
)or rid in 
(
    select rowid-2 from tbl 
    where value = 'error' 
    order by id 
) 

DEMO

+0

@aldmike, в чем проблема с этим? Я обработал этот сценарий, проверил мою демо? – jaychapani

+0

Ваша демонстрация была в порядке, я удалил свой комментарий. Мне нужно сейчас немного времени, чтобы интегрировать и проверить soultions :) Спасибо –

+0

@aldmike, если вы найдете это решение нормально, чем отметите его как ответ, чтобы другие могли ссылаться на него. – jaychapani

0
select id, value 
from test where id in (select id-1 from test where value = 'error') 

Это будет работать, если вы всегда ищете первый идентификатор за вашей ошибкой. Если может случиться, что вы пропустите идентификатор, вы можете использовать функцию MIN, чтобы получить ближайший существующий идентификатор.

+0

Это может случиться, к сожалению, я не знаю, как я могу с помощью функции MIN решить проблему. –

0

Попробуйте это:

SELECT id 
FROM thetable 
ORDER BY 
    CASE WHEN value = 'error' THEN value ELSE ID END 
DESC 
2

SQL Fiddle Demo


Я не знаю, если sqllite имеет рейтинг функции Wich бы решение намного проще, но следующее заявление должно работать на любом ANSI-92 совместимых СУБД.

Суть решения состоит в

  • Шаг 1: Получить все error идентификаторы
  • Шаг 2: Получить все идентификаторы < корневой идентификаторы с помощью предложения GROUP BY и соединения с тем же запросом, чтобы получить исходная ошибка ID
  • Шаг 3: Аналогично второму шагу, но спуститься на другой уровень.

SQL Заявление

SELECT ID 
FROM (
       -- Select the ROOT value 
       SELECT ID, 0 AS GroupID 
       FROM thetable 
       WHERE value = 'error' 
       UNION ALL 

       -- Selects the ROOT value - 1 
       SELECT MAX(t.ID) AS ID, te.ID AS GroupID 
       FROM thetable AS t 
         INNER JOIN (
         SELECT ID 
         FROM thetable 
         WHERE value = 'error' 
        ) AS te ON te.ID > t.ID 
       GROUP BY 
         te.ID 

       UNION ALL   

       -- Selects the ROOT value - 1 - 1 
       SELECT MAX(t.ID), te.ID 
       FROM thetable AS t 
         INNER JOIN (  
         SELECT MAX(t.ID) AS ID, te.ID AS GroupID 
         FROM thetable AS t 
           INNER JOIN (
            SELECT ID 
            FROM thetable 
            WHERE value = 'error' 
           ) AS te ON te.ID > t.ID 
         GROUP BY 
           te.ID 
        ) AS te ON te.ID > t.ID 
       GROUP BY 
         te.ID 
      ) AS t     

ORDER BY 
     ID 

Редактировать

FWIW: Если SQLite позволяет ранжирования функций и CTE, следуя заявление возвращает тот же результат, но гораздо более конденсируется.

;WITH q AS (
    SELECT ROW_NUMBER() OVER (ORDER BY ID) rn 
      , ID 
      , value 
    FROM thetable 
) 
SELECT q2.ID 
FROM q q1 
     INNER JOIN q q2 ON q2.rn BETWEEN q1.rn - 2 AND q1.rn 
WHERE q1.value = 'error' 
+0

Мне нужно немного времени :) Спасибо –

+0

Я не могу использовать второй, потому что в sqlite не существует ROW_NUMBER() или равно. (Если я хорошо прочитал), я попробую сначала –

+0

Хорошо, первый способ хорош на sqlite после интеграции. Только немного слишком много, и я должен понять. Спасибо, я буду использовать его! –

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