2008-09-19 3 views
2

Вот моя ситуация:Проблема, связанная с курсором/присоединением

В первой таблице содержится набор данных, в которых используется идентификатор для уникального идентификатора. Эта таблица имеет отношение «один-много» к примерно 6 другим таблицам.

Учитывая Таблицу 1 с идентификатором 001: таблицы 2 может иметь 3 строки с внешним ключом: 001 Таблицы 3 может иметь 12 строк с внешним ключом: 001 Таблицы 4 может иметь 0 строк с внешним ключом: 001 таблицы 5 может иметь 28 строк с внешним ключом: 001

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

Мой нынешний подход в псевдо-код будет выглядеть следующим образом:

select * from table 1 
foreach(result) { 
    print result; 
    select * from table 2 where id = result.id; 
    foreach(result2) { 
    print result2; 
    } 
    select * from table 3 where id = result.id 
    foreach(result3) { 
    print result3; 
    } 
    //continued for each table 
} 

Это означает, что один отчет может работать в соседнем капот 1000 запросов. Я знаю, что это чрезмерно, но мой sql-fu немного слаб, и я мог бы использовать некоторую помощь.

+0

какую базу данных вы используете это на? – chrisb 2008-09-19 15:43:54

+0

Это псевдокод? Если нет, на каком языке? Для меня это не похоже на transact-SQL. Я бы предложил что-то, если бы знал формат ответа ... – 2008-09-19 15:44:14

ответ

3

LEFT OUTER JOIN Tables2-N на Table1

SELECT Table1.*, Table2.*, Table3.*, Table4.*, Table5.* 
FROM Table1 
LEFT OUTER JOIN Table2 ON Table1.ID = Table2.ID 
LEFT OUTER JOIN Table3 ON Table1.ID = Table3.ID 
LEFT OUTER JOIN Table4 ON Table1.ID = Table4.ID 
LEFT OUTER JOIN Table5 ON Table1.ID = Table5.ID 
WHERE (CRITERIA) 
+0

Он только хочет распечатать данные из таблицы 1 один раз. Это выполнимо с вашей стратегией, но требует большей логики. Также обратите внимание, что план запроса от этого типа соединения имеет тенденцию быть довольно плохим, если у вас нет точно нужного набора индексов. – user11318 2008-09-19 15:48:55

+0

То, что вы вытаскиваете из базы данных, не обязательно должно быть тем, что вы печатаете. Этот запрос является правильным: клиентская логика должна отображать только данные Table1 при ее изменении. Любое программное обеспечение для создания отчетов сделает это для вас приятным. – 2008-09-19 16:17:15

1

Ах! Процедурный! Мой SQL выглядел бы так, если бы вам нужно было заказывать результаты из других таблиц после результатов из первой таблицы.

Insert Into #rows Select id from Table1 where date between '12/30' and '12/31' 
Select * from Table1 t join #rows r on t.id = r.id 
Select * from Table2 t join #rows r on t.id = r.id 
--etc 

Если вы хотите, чтобы сгруппировать результаты по начальным ID, используйте левое внешнее соединение, как уже упоминалось ранее.

1

Возможно, вам лучше использовать инструмент отчетности, например Crystal или Jasper, или даже XSL-FO, если вы живете. У них есть все, что нужно, чтобы справиться именно с этим. Это не то, что будет хорошо работать в сыром SQL.

Если формат всех строк (заголовков, а также всех деталей) одинаковый, также было бы довольно легко сделать это как хранимую процедуру.

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

0

Соедините все столы вместе.

select * from table_1 left join table_2 using(id) left join table_3 using(id); 

Затем вам нужно свернуть столбцы в коде, чтобы отформатировать отчет, как вы сочтете нужным.

1
SELECT * FROM table1 t1 
INNER JOIN table2 t2 ON t1.id = t2.resultid -- this could be a left join if the table is not guaranteed to have entries for t1.id 
INNER JOIN table2 t3 ON t1.id = t3.resultid -- etc 

ИЛИ если данные все в том же формате, что и вы могли бы сделать.

SELECT cola,colb FROM table1 WHERE id = @id 
UNION ALL 
SELECT cola,colb FROM table2 WHERE resultid = @id 
UNION ALL 
SELECT cola,colb FROM table3 WHERE resultid = @id 

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

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

2

Join не делает это для меня. Мне не нравится дезактивировать данные на стороне клиента.Все эти нули от левого соединения.

Вот комплексное решение, которое не использует Joins.

INSERT INTO @LocalCollection (theKey) 
SELECT id 
FROM Table1 
WHERE ... 


SELECT * FROM Table1 WHERE id in (SELECT theKey FROM @LocalCollection) 

SELECT * FROM Table2 WHERE id in (SELECT theKey FROM @LocalCollection) 

SELECT * FROM Table3 WHERE id in (SELECT theKey FROM @LocalCollection) 

SELECT * FROM Table4 WHERE id in (SELECT theKey FROM @LocalCollection) 

SELECT * FROM Table5 WHERE id in (SELECT theKey FROM @LocalCollection) 
0

Что я хотел бы сделать, это открыть курсоров по следующим запросам:

SELECT * from table1 order by id 
SELECT * from table1 r, table2 t where t.table1_id = r.id order by r.id 
SELECT * from table1 r, table3 t where t.table1_id = r.id order by r.id 

И тогда я бы ходить эти курсоры параллельно, печать результатов. Вы можете сделать это, потому что все отображаются в том же порядке. (Обратите внимание, что я бы предположил, что, хотя первичный идентификатор для таблицы1 может иметь имя id, он не будет имеет это имя в других таблицах.)

0

Все ли таблицы имеют одинаковый формат? Если нет, то если у вас должен быть отчет, который может отображать n различные типы строк. Если вас интересуют только те же столбцы, то это проще.

Большинство баз данных имеют некоторую форму динамического SQL. В этом случае вы можете сделать следующее:

create temporary table from 
select * from table1 where rows within time frame 

x integer 
sql varchar(something) 
x = 1 
while x <= numresults { 
sql = 'SELECT * from table' + CAST(X as varchar) + ' where id in (select id from temporary table' 
execute sql 
x = x + 1 
} 

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

Если отчет требует тех же 2 или 3 колонки для каждой таблицы можно изменить select * from tablex быть insert into и получить единый набор результатов в конце ...

Смежные вопросы