SQL: объединение 2 таблиц, а затем присоединение к другой. Есть ли лучший способ сделать это?

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

временная метка table1, zid, aaa

временная метка table2, zid, bbb

Идентификатор таблицы3, некоторые, другие, данные

Таким образом, таблицы 1 и 2 должны быть объединены и отсортированы по столбцам временных меток. Мне также нужно сохранить столбец aaa table1 и bbb table2 и иметь возможность различать, является ли это aaa или bbb. Затем мне нужно присоединиться к другой таблице через их столбец zid.

Вот мой рабочий sql для этого:

SELECT *

FROM 
    table3
    LEFT JOIN
    (
    SELECT  table1.timestamp AS timestamp, 
        table1.zid, 
        table1.aaa AS responses,
        'aaas'
    FROM table1

    UNION ALL
    SELECT  table2.timestamp AS timestamp, 
        table2.zid,
        table2.aaa AS responses,
        'bbbs'
    FROM table2

    ) aaasAndbbbs ON table3.id = aaasAndbbbs.zid

ORDER BY timestamp ASC;

Вышеприведенный sql делает именно то, что я хочу, но я хочу знать, есть ли лучший способ. Здесь я использую столбец «aaas», чтобы различать, является ли это aaa или bbb, что кажется немного хакерским. Есть ли предпочтительный способ делать то, что я хочу?


person red888    schedule 26.03.2014    source источник
comment
На самом деле вы не присоединяетесь к таблице1 и таблице2, вы просто объединяете наборы данных. Дополнительный столбец, который определяет, откуда взялось исходное поле, кажется правильным способом сделать это. Как еще вы могли бы узнать, поступили ли данные из столбца «aaa» или столбца «bbb» без какого-либо флага? Каково использование этих таблиц в бизнесе? «ааа» и «ббб» очень общие...   -  person N West    schedule 26.03.2014
comment
столбец aaas - это флаг, который я использую. Я также в настоящее время не могу изменить базу данных   -  person red888    schedule 26.03.2014
comment
@user1028270 user1028270: Можете ли вы рассказать немного больше о характере данных в таблице 1 и таблице 2? Я бы попытался избежать UNION ради производительности, если это возможно (например, если таблица1 содержит текущие данные, а таблица2 — исторические, запрос можно легко переписать без объединения).   -  person a1ex07    schedule 26.03.2014
comment
Это своего рода беспорядок, но в этих таблицах есть ввод текста пользователями в системе типа cms. Таблица 3 содержит информацию об основных потоках, таблица 1 — это обычный ответ, а таблица 2 — примечание, которое является просто специальным ответом. Ответы и примечания должны отображаться в хронологическом порядке с помощью временной метки, должны быть идентифицированы как ответ или примечание и присоединены к основному потоку с различной другой информацией. Я задал этот вопрос, потому что знаю, что профсоюзов следует избегать. В моем случае я думал, что это лучшее решение.   -  person red888    schedule 26.03.2014


Ответы (1)


Альтернативой может быть выполнение каждого отдельно, и вы увидите, что LEFT JOIN в таблице 3 дублируется. Однако я подозреваю, что если вы посмотрите на план выполнения как для вашей версии, так и для моей версии, они будут одинаковыми. Оптимизатор SQL Server должен быть достаточно умен, чтобы понять, что оба они делают одно и то же, и, следовательно, выполнять их одинаково. Я нахожу это немного более читаемым, чем ваше, но это мое предпочтение!

SELECT  table1.timestamp AS timestamp, 
    table1.zid, 
    table1.aaa AS responses,
    'aaas'
FROM table3 
LEFT JOIN table1 on table3.id = table1.zid

UNION

SELECT  table2.timestamp AS timestamp, 
    table2.zid,
    table2.aaa AS responses,
    'bbbs'
FROM table3
LEFT JOIN table1 on table3.id = table2.zid
ORDER BY timestamp ASC;
person sarin    schedule 26.03.2014
comment
OP выбирает из table3, а затем оставляет соединение с таблицей1, таблицей2, а не наоборот. Ваши LEFT JOIN должны быть RIGHT JOIN, чтобы вернуть те же результаты, что и в вопросе. - person a1ex07; 26.03.2014
comment
хм, попытался запустить это с правильными соединениями в соответствии с комментарием, и выполнение запроса занимает много времени... - person red888; 26.03.2014
comment
;) вместо того, чтобы добавлять правильные соединения, я поменял местами таблицы в предложении from и раунде соединения, который соответствует вашему запросу. Если вы сейчас измените их на правильные соединения, вы снова столкнетесь с моей ошибкой! Попробуйте ответить как есть. - person sarin; 26.03.2014
comment
Как выбрать другие столбцы из таблицы 3 с помощью этого запроса? - person red888; 26.03.2014
comment
Также с помощью этого запроса кажется, что я не могу использовать предложение where для поиска по идентификатору таблицы 3? Если я помещу следующую строку внизу этого запроса, он ничего не сделает: WHERE table3.id = '123456' - person red888; 26.03.2014
comment
Это потому, что он применяет предложение where только ко второму запросу. Если вы хотите применить предложение where к обоим, я бы согласился с вашим текущим ответом, иначе вы в конечном итоге дублируете код, и мой альтернативный ответ будет выглядеть беспорядочно. - person sarin; 26.03.2014
comment
На самом деле я мог бы использовать ваш, поскольку мой не может быть представлен из-за подзапроса. - person red888; 26.03.2014