2015-12-13 3 views
1

Вот что моя таблица выглядит следующим образом:Выберите из нескольких строк в одну строку с дефолтов

Table items 

    idx bigint unique 
    merkle char(64) 
    tag text 
    digest char(64) 

С idx уникален, я буду использовать оператор подстрочного [] для обозначения поля, соответствующее idx speficied, так например, merkle[i] Я имею в виду поле merkle в строке, которое имеет idx значение i.

То, что я хотел бы запрос, который для данного I, выбирает tag[i], digest[i], merkle[2 * i], merkle[2 * i + 1] со значениями по умолчанию для merkle[2 * i] и merkle[2 * i + 1], если ни одна строка не существует с тех idx значений.

Так, например, сказать, что у меня есть

idx merkle tag digest 
1  merk1 tag1 dig1 

Я хотел бы мой запрос, возвращающий tag1, dig1, "default", "default". Если у меня есть

idx merkle tag digest 
1  merk1 tag1 dig1 
2  merk2 tag2 dig2 

Я хотел бы получить tag1, dig1, merk2, "default", если у меня есть

idx merkle tag digest 
1  merk1 tag1 dig1 
2  merk2 tag2 dig2 
3  merk3 tag3 dig3 

Я хотел бы получить tag1, dig1, merk2, merk3, и так далее.

Как я могу это сделать? Можно ли сделать это всего за одну транзакцию с базой данных? (Конечно, я мог бы сделать это с тремя отдельными запросами, но это выглядит неэффективно.)

+0

технически проверить, существует ли строка [i * 2], вам нужен дополнительный выбор в любом случае – AdamSkywalker

+0

Действительно! Вот почему я решил использовать термин «транзакция»: я бы не знал, как это лучше выразить. Я имел в виду, что я хочу общаться с моей базой данных только один раз, не получая результаты отдельно с несколькими различными транзакциями? –

+0

Вам нужно получить только одну строку или одну строку для каждой строки таблицы? Я имею в виду, вы также хотите получить «tag2, dig2, merkle [2 * 2], merkle [2 * 2 + 1]» и т. Д.? –

ответ

4

Вы можете сделать это с помощью LEFT JOIN и COALESCE:

SELECT t1.idx, t1.tag, t1.digest, 
     COALESCE(t2.merkle, 'default'), 
     COALESCE(t3.merkle, 'default') 
FROM mytable AS t1 
LEFT JOIN mytable AS t2 ON t2.idx = 2 * t1.idx 
LEFT JOIN mytable AS t3 ON t3.idx = 2 * t1.idx + 1 

Это будет соответствовать каждой строке с idx = i с рядами с idx = 2 * i и idx = 2 * i + 1. Если совпадение ни с одним из этих индексов (или с обоими), то будет выбрано default.

+0

, вы имеете в виду' ON t2.idx = 2 * t1.idx' вместо 'i' ? –

+0

Блестящий и элегантный. Большое спасибо. –

+0

@NikosM. Да ты прав. Я исправил свой запрос. –

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