2015-05-20 7 views
3

Моя таблица:vocabularyКак выбрать смежные столбцы в MySQL

id   word 
-------------------------- 
    1   hello 
    2   hello 
    3   how 
    4   how 
    5   how 
    6   are 
    7   hello 
    8   hello 
    9   are 
    10   are 
    11   are 
    12   are 
    13   hello 

Я хочу select id from vocabulary where id=$id and {all rows that are both the same word and adjacent}

Примечание: Я хочу, чтобы оба из них: [ID = $ идентификатор] и [все строки, которые являются одним и тем же словом и рядом]

В fa кт, мне нужно к SELECT запроса, чтобы сделать что-то вроде этого: (три примеры)

  1. $id=1, результат: 1,2 // [1 для $id=1] - [2 за слово 1 и 2 являются одинаковыми и смежными]
  2. $id=6, результат: // [6 для $id=6]
  3. $id=10, результат: 9,10,11,12 // [10 для $id=10] - [9,11,12 за слово 10 совпадает с 9,11,12]
+0

Это проблема с запуском и завершением последовательности – Strawberry

+0

Что это значит? это невозможно? –

+1

Нет. Это значит, что теперь вы знаете, что делать в Google. – Strawberry

ответ

3

Это решение с использованием переменных:

SELECT id, word 
FROM (
    SELECT id,  
     @rnk:= CASE WHEN @word = word THEN @rnk 
        ELSE @rnk + 1 
       END AS rnk, 
     @word:= word AS word 
    FROM vocabulary, (SELECT @rnk:=0) as vars  
    ORDER BY id) s 
WHERE s.rnk = (
    SELECT rnk 
    FROM (
     SELECT id,  
      @r:= CASE WHEN @w = word THEN @r 
         ELSE @r + 1 
        END AS rnk, 
      @w:= word AS word 
     FROM vocabulary, (SELECT @r:=0) as vars  
     ORDER BY id) t 
    WHERE id = 10) -- 10 is equal to $id 

SQL Fiddle Demo

Тот же запрос повторяется два раза из-за отсутствия CTE s в MySQL. @rnk и @r переменные используются для идентификации островов непрерывных значений word в пределах vocabulary стол.

Второй запрос выбирает значение острова (например, @r = 5 для id = 10), а первое использует это значение для выбора всех записей, принадлежащих одному острову.

+0

Wow, работал правильно! tnx приятель ..! –

+0

Не могли бы вы дать краткое описание? –

+0

@stack Я думаю, что я дал краткое описание. Вы можете попробовать выполнить отдельно один из подзапросов, чтобы увидеть, что он возвращает. Затем вы поймете, что переменные '@ r',' @ rnk' имеют одинаковое значение для всех записей, относящихся к одной и той же группе значений, также называемых островами. –

3

Вот основной шаблон, который вы можете адаптировать к вашей цели ...

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,word VARCHAR(12) NOT NULL 
); 

INSERT INTO my_table VALUES 
(1 ,'hello'), 
(2 ,'hello'), 
(3 ,'how'), 
(4 ,'how'), 
(5 ,'how'), 
(6 ,'are'), 
(7 ,'hello'), 
(8 ,'hello'), 
(9 ,'are'), 
(10,'are'), 
(11,'are'), 
(12,'are'), 
(13,'hello'); 

SELECT a.id start 
    , MIN(c.id) end 
    FROM my_table a 
    LEFT 
    JOIN my_table b 
    ON b.id = a.id - 1 
    AND b.word = a.word 
    LEFT 
    JOIN my_table c 
    ON c.id >= a.id 
    AND c.word = a.word 
    LEFT 
    JOIN my_table d 
    ON d.id = c.id + 1 
    AND d.word = a.word 
WHERE b.id IS NULL 
    AND c.id IS NOT NULL 
    AND d.id IS NULL 
GROUP 
    BY a.id; 

+-------+------+ 
| start | end | 
+-------+------+ 
|  1 | 2 | 
|  3 | 5 | 
|  6 | 6 | 
|  7 | 8 | 
|  9 | 12 | 
| 13 | 13 | 
+-------+------+ 

Как McAdam331 предполагает, один из способов расширения этой идеи заключается в следующем:

SELECT * 
    FROM vocabulary 
    JOIN tmpTable 
WHERE id BETWEEN tmpTable.start AND tmpTable.end 
    AND tmpTable.start = $id; 
+0

em .. Честно говоря, я не получил его ..! :(Я сделал ваш код на http://sqlfiddle.com/ и проверил результат, но я не знаю, как я должен использовать его для себя ..? –

+0

@stack теперь, когда вы знаете начальную и конечную последовательности, вы можете сделать что-то вроде: 'SELECT * FROM vocabulary JOIN tmpTable WHERE id BETWEEN tmpTable.start AND tmpTable. end И tmpTable.start = $ id; 'Это просто грубый psuedocode. – AdamMc331

+0

aha, я думаю, что получил немного :) :) McAdam331 может добавить ваше предложение в качестве нового ответа (полностью :)) –

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