2013-10-09 2 views
1

Я хочу присоединиться следующие 2 таблицы в Postgres:SQL запрос соединить 2 таблицы

table1 (
    i1 character varying 
, i2 character varying 
, i3 character varying 
) 

table2 (
    i4 character varying 
, startorend character varying 
, begin integer 
, end character integer 
) 

table1 содержит следующие значения:

p1 p2 p3 
    p4 p10 p6 
    p7 p8 p9 
    p99 p199 p299 

table2 содержит следующие значения:

p4 begin 1 12 
    p4 end 13 14 
    p7 begin 19 20 
    p1 end 21 22 

Теперь я хочу присоединиться к двум таблицам, чтобы соблюдались следующие правила:

 
1. When table1.i1=table2.i4, then 
    1a. If there are 2 rows containing begin and end corresponding to table2, 
     then choose table2.begin and table2.end 
     from the begin and end columns respectively from table2.i4. 
    1b. If there is only 1 row containing begin or end corresponding to table2, 
     then assume and write the default value as end(9999) and begin(0). 

Применяя вышеуказанные правила, я получаю нижеуказанным таблице:

p4  1   14 
p1  0(default) 22 (as it just contains end column in table 2, therefore 0(begin) as default is inserted) 
p7  19   9999(default) (as it just contains begin column in table2, therefore 9999(end) as default is inserted) 

можно эффективно соединить таблицы, но нам возможность вставить значения по умолчанию, случайно?

+0

Так что таблица1 не имеет ничего общего с логикой, о которой вы упоминаете. Я прав? Можно ли предположить, что в столбце «beginorend» разрешены только «begin» или «end»? Может ли быть более двух записей заданного значения «i4»? –

+0

@ table1 важно, что есть соединение в таблице1.i1 = table2.i4 –

+0

Кажется, что начальные и конечные значения для 'startorend = 'begin'' всегда меньше тех же значений для' startorend =' end''. Кроме того, кажется, что для данной записи все числа в столбце begin меньше всех чисел в конце столбца. Правильны ли эти предположения? Пожалуйста, будьте понятны в ответе –

ответ

1
SELECT i4 
     ,CASE WHEN count(*) > 1 OR min(startorend) = 'begin' THEN min("begin") 
      ELSE 0 END AS the_begin 
     ,CASE WHEN count(*) > 1 OR min(startorend) = 'end' THEN min("end") 
      ELSE 9999 END AS the_end 
FROM table2 t2 
WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.i1 = t2.i4) 
GROUP BY i4 

Предполагая, чтоtable1.i1 является UNIQUE или имеет значение только то, что один или более подходящие строки существуют.

begin и end являются reserved words in the SQL standard. Вы не должны использовать их в качестве идентификаторов. Вот почему я дважды цитировал.

1

Вы должны быть в состоянии сделать это, создав вложенные элементы выбора для начального и конечного значений, выполнив внешнее объединение, а затем используя ISNULL, чтобы заменить значения по умолчанию, если не найдено совпадающих строк.

SELECT Table1.i1, 
     ISNULL(BeginValues.begin, 0), 
     ISNULL(EndValues.end, 9999) 
FROM Table1 LEFT OUTER JOIN 
     (SELECT i4, begin 
     FROM Table2 
     WHERE Table2.startorend = 'begin') AS BeginValues 
     ON Table1.i1 = BeginValues.i4 LEFT OUTER JOIN 
     (SELECT i4, end 
     FROM Table2 
     WHERE Table2.startorend = 'end') AS EndValues 
     ON Table1.i1 = EndValues.i4 
Смежные вопросы