2015-09-22 3 views
1

Мне нужно объединить две таблицы в один общий столбец, но я хочу поддерживать отношение «один к одному» в других двух столбцах. Например:Одно к одному присоединяется к MySQL

table_1

ID_C ID_ROW_C OPT 
C  1   10 
C  2   10 

table_2

ID_F ID_ROW_F OPT 
F  3   10 
F  4   10 

Мой запрос:

select * 
from table_1, table_2 
where table_1.OPT=table_2.OPT 

результат

ID_C ID_ROW_C OPT ID_F ID_ROW_F 
C  1   10 F  3 
C  1   10 F  4 
C  2   10 F  3 
C  2   10 F  4 

желаемого результата:

ID_C ID_ROW_C OPT ID_F ID_ROW_F 
C  1   10 F  4 
C  2   10 F  3 

или

ID_C ID_ROW_C OPT ID_F ID_ROW_F 
C  1   10 F  3 
C  2   10 F  4 

Как я могу сделать?

+1

Помимо поля 'OPT', как вы относите столбцы от каждой таблицы к другой? Вы получаете то, что ожидается (если вы только присоединитесь к столбцу «OPT», вы получите все комбинации с соответствующими строками) ... вам нужно определить некоторые критерии, чтобы связать другие строки. – Barranka

ответ

1

Что вам нужно сделать, это использовать JOIN.

SELECT * FROM table_1 
JOIN table_2 
ON table_1.OPT = table_2.OPT 

Более подробную информацию из руководства MySQL: https://dev.mysql.com/doc/refman/5.0/en/join.html

И соответствующего обсуждения переполнением стека на различных типах JOIN с: What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?

+0

Это не то, что я должен делать. Я хочу получить только 2 строки из этого запроса, а не 4. –

+1

Похоже, что ответ @ barranka должен помочь вам ближе, но я бы посмотрел на ваш дизайн таблицы, если это то, что вы хотите сделать. –

0

Поскольку вы не предоставляет каких-либо правило соотносить столбцы , вы получаете точно то, что вы должны получить: все строки обеих таблиц, которые выполняют отношение.

Однако, вы можете создать «искусственный» условие, чтобы получить то, что вы хотите ... это не красиво, но это будет работать:

select t1.id_c, t1.id_row_c 
    , t1.opt 
    , t2.id_f, t2.id_row_f 
from 
    (
     select @r_id_1 := (case 
        when @prev_opt_1 = table_1.opt then @r_id_1 + 1 
        else 1 
       end) as r_id 
      , table_1.* 
      , @prev_opt_1 := table_1.opt as new_opt_1 
     from (select @r_id_1 := 0, @prev_opt_1 := 0) as init_1 
      , table_1 
     order by table_1.opt, table_1.id_row_c 
    ) as t1 
    inner join (
     select @r_id_2 := (case 
        when @prev_opt_2 = table_2.opt then @r_id_2 + 1 
        else 1 
       end) as r_id 
      , table_2.* 
      , @prev_opt_2 := table_2.opt as new_opt_2 
     from (select @r_id_2 := 0, @prev_opt_2 := 0) as init_2, table_2 
     order by table_2.opt, table_2.id_row_f 
    ) as t2 on t1.opt = t2.opt and t1.r_id = t2.r_id 

Смотрите результат на SQL Fiddle.

Объяснение

Давайте возьмем первый подзапрос:

select @r_id_1 := (case 
      when @prev_opt_1 = table_1.opt then @r_id_1 + 1 
      else 1 
     end) as r_id 
    , table_1.* 
    , @prev_opt_1 := table_1.opt as new_opt_1 
from (select @r_id_1 := 0, @prev_opt_1 := 0) as init_1 
    , table_1 
order by table_1.opt, table_1.id_row_c 

В статье from для этого запроса, я объявляю две пользовательские переменные и инициализировать их к нулю. Переменная @r_id_1 будет увеличиваться на единицу, если предыдущее значение @prev_opt_1 равно текущему значению opt или сбрасывается до 1, если значение отличается. Переменная @prev_opt_1 примет значение opt столбец после значение переменной @r_id_1. Это означает, что для каждого значения opt переменная @r_id_1 будет иметь возрастающее значение.

Второй подзапрос делает то же самое для другой таблицы.

И наконец, запрос внешнего запроса объединяется с подзапросами, используя optи возрастающий идентификатор.

Потратьте время, чтобы понять, что происходит за сценой (выполнить каждый подзапрос в отдельности и посмотреть, что произойдет).


Как я уже сказал, это решение «искусственное» ... это способ получить то, что вам нужно, но, чтобы избежать этого грязных и довольно сложных жестких решений, вы должны пересмотреть свои таблицы, и сделать их более легкими для связи друг с другом.

Надеюсь, что это помогает

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