Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   sql-запрос с join'ами (http://forum.oszone.net/showthread.php?t=148697)

M1sha 23-08-2009 20:13 1201369

sql-запрос с join'ами
 
Всем привет.

Столкнулся со следующей проблемой:

Пишу программу на яве, работающую с IBM DB2. В программе есть ситуация, в которой надо реализовать генерацию sql-запроса с join'ами для нескольких таблиц из базы. Программе известно какие поля необходимо получить и из каких таблиц, так же известно по средством каких полей связаны таблицы. Притом последнюю информацию достаю из системной таблицы SYSRELS, поэтому она как бы не в явной форме, ее приходится анализировать, да и всегда программа работает с разными БД.

Знающие люди, подскажите как правильно составить этот sql-запрос, а то мой далеко не на всех ситуациях тестирование выдерживает. Как вообще из теории должен строиться такой запрос, а то может у меня в базовых знаниях проблемы, потому что с SQL впервые работаю.

Спасибо.

Delirium 24-08-2009 01:05 1201523

M1sha, что вы хотите услышать от нас, если не привели никакой конкретной информации? Приведите свой пример, пример того, что нужно, и т.п. Писать вы можете на чем угодно, главное - какой SQL используется и т.п.
К примеру, только в Firebird есть 3 диалекта SQL, и ни один из них не похож на синтаксис SQL от MS SQL Server и другие языки. Конкретизируйте вопрос.

M1sha 24-08-2009 18:35 1202103

Хорошо, сейчас постараюсь раскрыть более подробно.

Возьмем такую базу:




5 таблиц, 4 связи.

Теперь о программе..пользваотель запустил программу, выбрал нужные ему поля из разных таблиц и получил форма для просмотра данных.

Допустим пользователь выбрал следующие поля:

AUTO.REG_NOMER, AUTO.ID_COLOUR, COLOUR.COLOUR, VLAD.FAM, VLAD.NAME

Дальше в программе анализирую с одной или с несколькими таблицами работает пользователь, после начинаю формировать sql-запрос.

Из системной таблице беру информацию о том как связаны между собой таблицы..вот её фрагмент:




Дальше начинаю формировать sql-запрос. В данной ситуации получается следующий:

SELECT AUTO.REG_NOMER, AUTO.ID_COLOUR, COLOUR.COLOUR, VLAD.FAM, VLAD.NAME FROM COLOUR INNER JOIN AUTO ON COLOUR.ID_COLOUR=AUTO.ID_COLOUR INNER JOIN VLAD ON VLAD.ID_VLAD=AUTO.ID_VLAD

+ еще сортировку добавляю, но сейчас ее опустим, с ней все просто..

Теперь проблема. Проблема у меня со второй частью запроса, то есть то, что идет после FROM. Конечно в ряде случаев она генерируется удачно, но не во всех. Поэтому хочу спросить следующее:

Есть ли какие-то строгие правила формирования таких запросов..ну что первым указывать, а что вторым?
Может где-то можно найти примерный алгорит решения это задачи? может кто встречал?

По поводу диалекта SQL не знаю что сказать. Я с ним работаю впервые и пока тяжело воспринимаю. Хочется начать с нуля..с простых вещей, все расмотреть, разобрать, но сейчас поджимает время и мою программу надо привести в рабочий вид, поэтому обращаюсь к вам.

Delirium 25-08-2009 01:22 1202352

Вы знаете, а я бы не стал так извращаться с динамической выборкой данных из нескольких таблиц. Я бы сделал проще:
Код:

Select
    vlad.*,
  [auto].*,
  dej.*,
  v_viezd.*,
  colour.*
from vlad, [auto], dej, v_viezd, colour
where
            [auto].id_vlad=vlad.id_vlad and
            auto.id_colour=color.id_colour and
            v_viezd.id_auto=auto.id_auto and
            dej.id_dej=v_viezd.id_dej

вместо * надо подставить все поля из каждой таблицы.
В итоге я получу таблицу со ВСЕМИ полями из всех таблиц. И пользователь пусть себе выбирает столбцы какие хочет, те, что не будут выбраны, отображать не надо будет.

А если уж вы хотите работать с JOIN'ами, то просто создайте копию таблиц в MS Access и мастером создайте запрос. Затем откройте запрос в виде SQL и получите готовый код со всеми полями и JOIN'ами :)

M1sha 25-08-2009 11:15 1202584

К сожалению моя программа и должна решать извращение с динамической выборкой :( Поэтому приходить к решению, с выбором всех полей не очень хочется...да и все равно его придется генерировать не через MS Access, а программно, посколько прога должна работать с ЛЮБОЙ БД.

Думаю решение с WHERE мне тоже не подойдет, ведь тут нет тех возможностей как с inner join, outer join (left, right, full) и cross join...хотя я могу ошибаться)

Решил попробовать сделать запрос для все такблиц с JOIN'ами, но я немного недопонимаю как его строить..

SELECT *те таблицы, которые нам нужны* FROM *какую таблицу изначально указывать тут?* INNER JOIN *тут указывать ту, у которой первичный ключ или внешний?*ON COLOUR.ID_COLOUR=AUTO.ID_COLOUR

Собственно вопросы в самом запросе. Спасибо.

Delirium 26-08-2009 01:04 1203312

Цитата:

Цитата M1sha
SELECT *те таблицы, которые нам нужны* FROM *какую таблицу изначально указывать тут?* INNER JOIN *тут указывать ту, у которой первичный ключ или внешний?*ON COLOUR.ID_COLOUR=AUTO.ID_COLOUR »

Ну я же вам написал, сделайте макет в ACCESS, и посмотрите на код SQL. Он как раз и покажет, в каком порядке надо ставить JOIN'ы :) А потом просто портируйте запрос в нужном виде в свою программу:)

M1sha 26-08-2009 10:16 1203515

Delirium, меня интересуется не столь сам запрос для этой базы, а как бы строгие правила построения таких запросов, потому что для широкого ряда выборок у меня удается его сгенерировать, но для некоторых нет..Я достаточно много гуглил, но что-то это в талковом виде не встретил :(

Цитата:

Цитата Delirium
[auto].*, »

А что обозначает такое выделение таблицы?

kim-aa 26-08-2009 22:50 1204176

Лично я бы крайне не рекомендовал использовать JOIN при данных условиях (
Цитата:

Цитата M1sha
посколько прога должна работать с ЛЮБОЙ БД. »

) по следующим причинам:

1) JOIN как операция не входит в реляционную алгебру.

2) Каждая фирма реализует этот оператор по своему.
В моей практике был случай когда при переходе с MS SQL 6.x на 7.0, 2000 производительность запросов резко упала
(с полуторы минуты до 20 минут), проблема была связана именно со сменой MICROSOFT реализации JOIN
(в 6й ветке он был "бинарным", а в 7й реализовывался SQL-интерпретатором при помощи вложенных SELECT)

Delirium 27-08-2009 01:10 1204252

Цитата:

Цитата M1sha
Цитата Delirium:
[auto].*, »
А что обозначает такое выделение таблицы? »

Таким образом я указываю, что это имя таблицы(в кавычках), а не зарезервированная служебная команда SQL. К примеру, часто поле в базе называют SUM, а это функция sql. Вот чтобы интерпретатор не путался, такие имена заключаются в кавычки.
Цитата:

Цитата M1sha
Delirium, меня интересуется не столь сам запрос для этой базы, а как бы строгие правила построения таких запросов »

Повторю в третий раз: сделайте макет в Access, вы увидите тогда, поле какой таблицы должно быть слева от JOIN, а какое справа и т.д.

А еще лучше - послушайте совета kim-aa, и реализовывайте не через JOIN. Через Where ваш запрос будет работать в любой БД и проблем меньше с этими INNER join, LEFT join и т.п.

M1sha 27-08-2009 21:02 1204887

Delirium, kim-aa, спасибо за разъяснения.

Цитата:

Цитата Delirium
Вы знаете, а я бы не стал так извращаться с динамической выборкой данных из нескольких таблиц. Я бы сделал проще:
Код:
Select
vlad.*,
[auto].*,
dej.*,
v_viezd.*,
colour.*
from vlad, [auto], dej, v_viezd, colour
where
[auto].id_vlad=vlad.id_vlad and
auto.id_colour=color.id_colour and
v_viezd.id_auto=auto.id_auto and
dej.id_dej=v_viezd.id_dejвместо * надо подставить все поля из каждой таблицы.
В итоге я получу таблицу со ВСЕМИ полями из всех таблиц. И пользователь пусть себе выбирает столбцы какие хочет, те, что не будут выбраны, отображать не надо будет. »

Попробовал сделать так, да действительно все работает..но вот как быть, если мне надо получить только те строки, для которых существует соответствие записей главной и присоединяемой таблицы?? Вот у меня в тамблице АВТО 5 записей, а в таблице КОЛОР 10 цветов записано. Беру таблицу АВТО выбираю все поля и присоединяю таблицу КОЛОР, а беру от туда расшифровку цвета. Когда я использую INNER JOIN, то результатом запроса получает 5 записей...а когда делаю с WHERE, то их 15..как быть?

// 21:15 так же 15 записей получается даже в случае с одной таблицей


22:55

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

А пока благодарю все за помощь, за советы:-)


Время: 02:40.

Время: 02:40.
© OSzone.net 2001-