Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Выборка из неск-х таблиц


Автор: Ignat 15.9.2004, 10:55
Многоуважаемый ALL!
Возникла такая необходимость получить одним селектом один набор данных из нескольких таблиц с разной структурой, но при этом в этих таблицах некоторые поля одноименные. Например:
table1
id,name,description,flag
table2
id,name,content,date,flag

соединение таблиц даст набор данных, например:
id,name,description,flag,id,name,content,date,flag
т.е. произведение.

UNION, само собой, не прокатывает из-за разницы в структуре.

а можно ли получить такой набор данных, в котором структура будет результирующей, например:
id,name,description,flag,content,date
соответственно в тех строках, которые взяты из первой таблицы content и date будут NULL
аналогично для строк из второй.

Вообще возможно такое в SQL92?
Если есть мысли - пишите, любая идея мне интересна.

Спасибо!

Автор: boevik 15.9.2004, 11:08
Ignat, уверен что UNION не прокатывает?
А если так:
Код

SELECT id,name,description,flag, NULL, NULL, NULL, NULL, NULL
FROM table1
SELECT NULL, NULL, NULL, NULL, id,name,content,date,flag
FROM table2


Или full join для связи двух тавлиц по id
Код
SELECT *
FROM table1 FULL JOIN table2 ON table1.id = table2.id

Автор: Akina 15.9.2004, 11:31
Ignat
Если одноименные поля еще и одинаковые данные хранят - то какого черта? вынести в отдельную таблицу и привязать к ней различающиеся данные. Выборку делать тупым множественным inner join.

Автор: Ignat 15.9.2004, 11:50
boevik, подозреваю, что я не правильно изложил проблему.
Первый запрос даст набор данных в таком виде (если я не путаю):
Цитата
  id,    name,  description,  flag,      id,  name,  content,          date,      flag
    1,    some,            text,    01, NULL,    NULL,      NULL,          NULL,    NULL
NULL,  NULL,          NULL, NULL,      3,s_name,  big_text,2004-01-01,      11


А можно ли такой результат получить?
Код
  id,     name,  description,   flag,    content,           date  
   1,     some,             text,    01,         NULL,          NULL  
  3,  s_name,           NULL,    11,    big_text, 2004-01-01


C full join'ом проблема - в MySQL его нет, а попросил я в SQL92, потому что меня устраивают подселекты (в отличие от MYSQL), хотя это в данном случае мало чем может помочь.

Автор: boevik 15.9.2004, 12:12
Тогда так:
Код
SELECT id,name,description,flag, NULL, NULL, NULL
FROM table1
SELECT id,name, NULL, NULL, content,date,flag
FROM table2


Если есть одинаковые ID, то что надо получить?

Автор: Ignat 15.9.2004, 12:26
Akina, не выйдет - это таблицы разных модулей, а будут ли они зависит от конфигурации.

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

Сейчас думаю, чем так извращаться, наверное, надо сделать таблицы с одинаковой стуктурой, хоть и с избыточными данными.

Автор: <Spawn> 15.9.2004, 13:21
Ignat А чем тебе UNION не нравиться? Или я тоже тебя не правильно понялsmile.gif ?
П.С. Если опять не то, то приведи полные исходные данные и конечные. Так будет понятнее.

Автор: Akina 15.9.2004, 13:45
Ignat
Цитата
это таблицы разных модулей

В таком случае где гарантия что записи из таблиц с одинаковым, к примеру, ID, содержат также одинаковые name и flag? или это ГАРАНТИРОВАНО?

Автор: Ignat 15.9.2004, 13:52
Код
CREATE TABLE bl2mod (
 bl_id int(11) unsigned NOT NULL default '0',
 rec_id int(11) unsigned NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE blocks (
 id int(11) unsigned NOT NULL auto_increment,
 name varchar(255) NOT NULL default '',
 template int(11) unsigned NOT NULL default '0',
 mod_id int(11) unsigned NOT NULL default '0',
 PRIMARY KEY  (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE hierarhy (
 id int(11) unsigned NOT NULL auto_increment,
 name varchar(255) NOT NULL default '',
 title varchar(255) NOT NULL default '',
 cleft int(11) unsigned NOT NULL default '0',
 cright int(11) unsigned NOT NULL default '0',
 clevel int(11) unsigned NOT NULL default '0',
 flags int(16) unsigned NOT NULL default '0',
 template int(11) unsigned NOT NULL default '0',
 `date` datetime NOT NULL default '0000-00-00 00:00:00',
 PRIMARY KEY  (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE modules (
 id int(11) unsigned NOT NULL auto_increment,
 name varchar(255) NOT NULL default '',
 flags int(16) unsigned NOT NULL default '0',
 table_name varchar(255) NOT NULL default '',
 PRIMARY KEY  (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE news (
 id int(11) unsigned NOT NULL auto_increment,
 content text NOT NULL,
 `start` datetime NOT NULL default '0000-00-00 00:00:00',
 finish datetime NOT NULL default '0000-00-00 00:00:00',
 period int(5) NOT NULL default '0',
 flags int(16) NOT NULL default '0',
 PRIMARY KEY  (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE o2bl (
 obj_id int(11) unsigned NOT NULL default '0',
 bl_id int(11) unsigned NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE static (
 id int(11) unsigned NOT NULL auto_increment,
 content text NOT NULL,
 flags int(16) NOT NULL default '0',
 PRIMARY KEY  (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Это таблицы, их больше, но остальные не принципиальны в данный момент.
Запрос №1:
Код
SELECT blocks.id, modules.table_name
FROM modules, blocks, o2bl
WHERE modules.id = blocks.mod_id AND blocks.id = o2bl.bl_id AND o2bl.obj_id = (
SELECT c.id
FROM `hierarhy` a, `hierarhy` b, `hierarhy` c
WHERE c.cleft
BETWEEN b.cleft AND b.cright AND c.title = 'licens' AND b.cleft
BETWEEN a.cleft AND a.cright AND b.title = 'about' AND a.clevel = 1 AND a.title = 'root' );

С этого я поимел имена таблиц, e.g. news и static.

Теперь мне как-то надо состряпать новый запрос, чтобы выбрать конечные данные из таблиц, например, news и static в один набор данных.

<Spawn>, UNION позволяет объединить результаты запросов при полном совпадении структур данных, или я не прав?

Добавлено @ 13:54
Akina, id гарантированно, флажки - нет.

Добавлено @ 13:58
что-то я хреново объясняю.
у меня есть желание, чтоб при объединении таблиц, при совпадении имен полей данные клались в одно и тоже поле, но в разных строках, если совпадений по полям нет, то появится такое поле, где для строчек из другой таблицы стоит NULL.

Блин, всё равно фраза мутная.

Автор: <Spawn> 15.9.2004, 14:31
При использовании UNION необходимо лишь, чтобы типы выбираемых полей каждого селекта совпадали и было одинаковое количество выбираемых полей, то есть тебе, как уже сказал boevik, нужно сделать следующее:

SELECT id, name, description, NULL, NULL
FROM table1
UNION
SELECT id, name, NULL, NULL, content
FROM table2

т.е. за место несуществующих полей подставляешь NULL, который совместим со всеми типами данных

П.С. To Admin - чего то не то с парсером SQL кода - вырезается ключевое слово UNION

Автор: Ignat 15.9.2004, 14:42
Спасибо всем. Наконец догнал smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)