2015-09-03 3 views
0

У меня есть две таблицы, одна из которых содержит информацию о лицах и посылке. Каждая строка в этой таблице уникальна. Нет повторных данных. Это нечто следующее:Объединение двух таблиц, один с одинаковыми уникальными строками, а другой с несколькими соответствующими строками

enter image description here

Кроме того, у меня есть эта таблица, которая включает в себя объяснение этих уникальных строк, показанных выше. Например

enter image description here

Как вы можете видеть, что есть 3 разные объяснения просто «Джейн». Я хочу добавить объяснения1, explain2, explain3 столбцы в первую таблицу и обновить эти поля с соответствующей информацией из второй таблицы.

Однако проблема возникает именно в этом пункте. Когда я выбираю, давайте скажем поля «Имя», «Фамилия», «Посылка» и «Блок» из обеих таблиц для соответствия, все столбцы объяснения, которые необходимо обновить соответствующими объяснениями, заполняются только с первым объяснением. В качестве примера все поля объяснения1, explain2, explain3 для «Jane Black» в первой строке первой таблицы обновляются только с помощью «Lorem ipsum dolor sit». Остальные объяснения со второй таблицы остаются неиспользованными.

Подводя итог, интересно, как я подхожу к проблеме не разумно или есть способ решить эту проблему после моего подхода? (я использую как доступ, так и mysql как RDBMS и т. Д.)

+1

Почему вы хотите добавить 3 колонки в первую таблицу? Что произойдет, когда вы получите ситуацию, когда есть 4 объяснения, добавите ли вы четвертый столбец? Мне кажется, что изменение, которое вы хотите сделать, - это регрессия, а не улучшение * (вы денормализуете данные, когда в общем вы должны нормализовать данные) *. Мой совет: не делать то, что вы предлагаете. – MatBailie

+0

В Oracle я использовал бы функцию LISTAGG, чтобы объединить объяснение того же имени/фамилии. Затем я присоединяюсь к этому результату на ваш основной стол. Посмотрите, есть ли у вас способ/замена функции LISTAGG в ms-access. – Utsav

+1

'выберите имя, фамилию, парцеллу и блок, group_concat (объяснение) из группы table2 No, Name, Surname' – splash58

ответ

0

Довольно противный способ сделать это и не проверять.

Это использует 3 дополнительных запросов, которые получают необходимые объяснения для 1-го, 2-го и 3-го объяснения столбцов: -

SELECT t1.name, t1.parcel, t1.block, t1.share, t1.id, t2a.explanation, t2b.explanation, t2c.explanation 
FROM table1 t1 
LEFT OUTER JOIN 
(
    SELECT t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation 
    FROM table2 t21 
    LEFT OUTER JOIN table2 t22 
    ON t21.name = t22.name AND t21.surname = t22.surname AND t21.parcel = t22.parcel AND t21.block = t22.block AND t21.share = t22.share AND t21.id = t22.id AND t1.o > t2.no 
    GROUP BY t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation 
    HAVING COUNT(t22.No) = 0 
) t2a ON t1.name = t2a.name AND t2.surname = t2a.surname AND t1.parcel = t2a.parcel AND t1.block = t2a.block AND t1.share = t2a.share AND t1.id = t2a.id 
LEFT OUTER JOIN 
(
    SELECT t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation 
    FROM table2 t21 
    LEFT OUTER JOIN table2 t22 
    ON t21.name = t22.name AND t21.surname = t22.surname AND t21.parcel = t22.parcel AND t21.block = t22.block AND t21.share = t22.share AND t21.id = t22.id AND t1.o > t2.no 
    GROUP BY t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation 
    HAVING COUNT(t22.No) = 0 
) t2b ON t1.name = t2b.name AND t2.surname = t2b.surname AND t1.parcel = t2b.parcel AND t1.block = t2b.block AND t1.share = t2b.share AND t1.id = t2b.id 
LEFT OUTER JOIN 
(
    SELECT t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation 
    FROM table2 t21 
    LEFT OUTER JOIN table2 t22 
    ON t21.name = t22.name AND t21.surname = t22.surname AND t21.parcel = t22.parcel AND t21.block = t22.block AND t21.share = t22.share AND t21.id = t22.id AND t1.o > t2.no 
    GROUP BY t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation 
    HAVING COUNT(t22.No) = 0 
) t2c ON t1.name = t2c.name AND t2.surname = t2c.surname AND t1.parcel = t2c.parcel AND t1.block = t2c.block AND t1.share = t2c.share AND t1.id = t2c.id 

Simpler но немного менее надежным является использование GROUP_CONCAT и SUBSTRING_INDEX. Это получит строку из всех объяснений, разделенных случайной строкой (я использовал здесь ~ # ~ ## здесь), а затем разделил ее на другую для каждого столбца. Это, конечно же, не удастся, если объяснение будет содержать строку, которую вы используете для ее разграничения.

SELECT t1.name, 
     t1.parcel, 
     t1.block, 
     t1.share, 
     t1.id, 
     SUBSTRING_INDEX(GROUP_CONCAT(t2.explanation ORDER BY t2.no SEPARATOR '~#~#~'), '~#~#~', 1), 
     IF(COUNT(t2.no) >= 2, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.explanation ORDER BY t2.no SEPARATOR '~#~#~'), '~#~#~', 1), '~#~#~', -1), NULL), 
     IF(COUNT(t2.no) >= 2, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.explanation ORDER BY t2.no SEPARATOR '~#~#~'), '~#~#~', 2), '~#~#~', -1), NULL) 
FROM table1 t1 
LEFT OUTER JOIN table2 t2 
ON t1.name = t2.name AND t2.surname = t2.surname AND t1.parcel = t2.parcel AND t1.block = t2.block AND t1.share = t2.share AND t1.id = t2.id 
GROUP BY t1.name, 
     t1.parcel, 
     t1.block, 
     t1.share, 
     t1.id 

Но лично я, вероятно, сделаю это в коде вне SQL.