Xpoint
   [напомнить пароль]

select * из нескольких таблиц

Метки: [без меток]
[арх]
2005-12-06 17:13:08 [обр] Сергей Петров(0/10)[досье]

Нужно сделать запрос вида select table1.*, table2.* from table1,table2 так чтобы в результате отличить колонки одной таблицы от колонки другой.

Как это можно сделать, не перечисляя каждую из колонок?

Вообще, речь идет о Mysql + PHP, но очень желательна переносимость на pgsql, mssql и т.п., поэтому пишу сюда.

спустя 2 часа 44 минуты [обр] Закиров Руслан(12/343)[досье]
Узнав сколько колонок в таблицах, то можно потом массив разбить на две части.
спустя 14 часов [обр] Сергей Петров(0/10)[досье]

А вот такой вопрос:

в mysql я мог бы написать select table1.*, 'delimeter', table2.* from table1,table2

Подозреваю, что в каком-нибудь Oracle это не сработает. Есть ли возможность сделать подобный запрос универсальным?

спустя 25 минут [обр] GRAy(8/259)[досье]

Сергей Петров[досье] Что значит "отличить"? Если в таблицах есть колонки с одинаковыми названиями, селект просто не выполнится. Т.е. он может выполнится в интерактивной среде типа SQLPlus, т.к. эта среда сама создаёт разные алиасы для колонок, но при запросе из программного кода, если вы в явном виде не укажете эти алиасы произойдёт кофликт имён. Если таких колонок нет, то способ с 'delimeter' как раз подойдёт, только надо ещё дополнить его до такого вида:

select table1.*, 'delimeter' as delimeter, table2.* from table1,table2

т.е. задать колонке со значением delimeter ещё и алиас - любой, который вы сочтёте удобным, главное чтобы он не совпадал с названием колонок в ваших таблицах.

P.S. А вообще-то это не очень хорошая идея использовать селекты с *.

спустя 9 минут [обр] Сергей Петров(0/10)[досье]

Я знаю, что * использовать не следует, но, к сожалению, других вариантов нет.

Насчет конфликта: действительно. не подумал.

Вопрос: неужели нельзя написать что-то вроде select table.* as 'table_'.* from table ?

В таком виде - очевидно, нельзя. Но может быть как-то?

спустя 1 час 21 минуту [обр] GRAy(8/259)[досье]
Сергей Петров[досье] Никак. Вы не должны этого хотеть (c). Может объясните для чего вам такая выборка? Где и как вы собираетесь обрабатывать её результаты?
спустя 2 минуты [обр] Сергей Петров(0/10)[досье]

В PHP.

Есть несколько классов. Один находится с другим в отношении композиции. Для автоматического маппинга из базы в классы - мне нужно сделать такую выборку.

Варианта я вижу только два: либо делать select *, либо определять доп. информацию о том, какая переменная соответствует какому полю в БД. Второе делать очень не хочется.

спустя 13 минут [обр] Алексей Севрюков(7/1292)[досье]
Сергей Петров[досье] В таких случаях Ваш класс должен вытягивать структуру таблицы и оперировать с ней. Тогда проблем быть не должно. И переменные в классе называть так же как и поля в таблице, например хранить в хэше.
спустя 2 минуты [обр] Сергей Петров(0/10)[досье]

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

В таком случае - подскажите, как это делать проще всего? И универсальнее всего.

спустя 29 минут [обр] Алексей Севрюков(7/1292)[досье]
Сергей Петров[досье] Мне почему то не кажется это странным. Очень даже красивый вариант. ИМХО.
спустя 3 часа 55 минут [обр] Закиров Руслан(12/343)[досье]

Сергей Петров[досье] Автоматических маперов существует много:
Например в perl: DBI::Class, Alzabo, DBI::Rose (не помню точно названия), DBIx::SearchBuilder (Jifty::DBI aka SB 2.x)... и это, я просто уверен, неполный список. Так же уверен, что в PHP есть тоже свой набор решений, советую посмотреть, задачка-то непростая.

О получении инфы о классе:

  1. Динамически вытягивать инфу о таблице и кешировать. Методы есть (должны быть частью библиотеки доступа к БД), на крайний случай можно использовать 'SHOW FIELDS FROM "<table_name>";' и разбарать самому.
  2. Использовать "class factory". Фабрика (скрипт) генерирует классы по существующему описанию таблиц, соответственно генерируются методы, которые возвращают список полей, их типы и прочие метаданные.
  3. Использовать "DB schema factory". Фабрика генерирует схему таблиц по существующим классам.
  4. Существуют варианты, когда структура таблиц не зависит от данных классов совсем, а значения свойств записываются в определенные таблицы в зависимости от типов данных с привязкой к сущьностям классов по их типу и идентификатору сущности.
  5. ... и другие (мне неизвестные или забытые)

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

спустя 25 минут [обр] Сергей Петров(0/10)[досье]

Про системы маппинга я более-менее в курсе. И как оно в RubyOnRails устроено, и как в Django.

Так сложилось, что пишу свою. Под конкретную задачу.

Видимо, придется вытаскивать инфу о таблице.

спустя 7 часов [обр] Lynn «Кофеман»(0/571)[досье]
GRAy[досье]
Если в таблицах есть колонки с одинаковыми названиями, селект просто не выполнится.

С какого перепугу он не выполнится?

Сергей Петров[досье]
Собсвенно запрос select t1.*, 'xxx', t2.* from t1, t2 ничему не противоречит. Потом пройтись по первой строчке результата в поисках 'xxx' это и будет наш разделитель. Всё, что до него — из первой таблицы, что после — из второй.

спустя 13 часов [обр] GRAy(8/259)[досье]
Lynn «Кофеман»[досье] Насколько мне известно, в SQL таблице (или выборке) не может быть двух колонок с одинаковым названием (идентификатором). Некоторые среды исполнения автоматически разрешают конфликт имён для таких случаев, но это не значит, что так правильно.
спустя 18 минут [обр] Lynn «Кофеман»(0/571)[досье]

Хм. В таблице конечно не может быть двух колонок с одинаковым названием, но вот в выборке — легко. Во всех учебниках по SQL написан пример self-join'а типа

select a.name, a.id, b.name, b.id from mytable as a, mytable as b where a.parentid = b.id;

Так что у вас какая-то странная информация.

В конце концов в той же документации по mysql_fetch_array() есть такая фраза:

If two or more columns of the result have the same field names, the last column will take precedence. To access the other column(s) of the same name, you must use the numeric index of the column or make an alias for the column. For aliased columns, you cannot access the contents with the original column name.

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

спустя 32 минуты [обр] GRAy(8/259)[досье]

Lynn «Кофеман»[досье] Вот сейчас попробовал сделать в Oracle:

declare 
  cursor c1 is
    select a.object_name, b.object_name
    from all_objects a, all_objects b;
  a c1%rowtype;
begin
  open c1; close c1;
end;

Выдал ошибку - нужен алиас. Хотя, я с вами соглашусь, это видимо исключительно проблема PL\SQL. Что впрочем и понятно. Ни JDBC ни mysql_fetch_array() не должны в таком случае ругаться, ибо у них по-умолчанию есть доступ к колонкам по индексу и конфликт разрешим с помощью него. По причине конфликта имен колонок в таблице нельзя создать View на базе подобного селекта - ну это тоже совершенно предсказуемое поведение.

Powered by POEM™ Engine Copyright © 2002-2005