可能与 Cursor/Join 有关的问题

发布于 2024-07-06 05:53:18 字数 633 浏览 13 评论 0原文

这是我的情况:

表一包含一组使用 id 作为唯一标识符的数据。 该表与大约 6 个其他表具有一对多关系。

给定表 1,ID 为 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 有点弱,我需要一些帮助。

Here is my situation:

Table one contains a set of data that uses an id for an unique identifier. This table has a one to many relationship with about 6 other tables such that.

Given Table 1 with Id of 001:
Table 2 might have 3 rows with foreign key: 001
Table 3 might have 12 rows with foreign key: 001
Table 4 might have 0 rows with foreign key: 001
Table 5 might have 28 rows with foreign key: 001

I need to write a report that lists all of the rows from Table 1 for a specified time frame followed by all of the data contained in the handful of tables that reference it.

My current approach in pseudo code would look like this:

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
}

This means that the single report can run in the neighbor hood of 1000 queries. I know this is excessive however my sql-fu is a little weak and I could use some help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

时光是把杀猪刀 2024-07-13 05:53:18

表 1 上的左外连接表 2-N

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)

LEFT OUTER JOIN Tables2-N on 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)
屋顶上的小猫咪 2024-07-13 05:53:18

加入不适合我。 我讨厌必须在客户端理清数据。 所有这些来自左连接的空值。

这是一个不使用联接的基于集合的解决方案。

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)

Join doesn't do it for me. I hate having to de-tangle the data on the client side. All those nulls from left-joining.

Here's a set-based solution that doesn't use 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)
把回忆走一遍 2024-07-13 05:53:18

啊! 程序! 如果您需要在第一个表的结果之后对其他表的结果进行排序,那么我的 SQL 将如下所示。

插入 #rows 从表 1 中选择 id,其中日期在“12/30”和“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 对结果进行分组,请使用左外连接,如前所述。

Ah! Procedural! My SQL would look like this, if you needed to order the results from the other tables after the results from the first table.

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

If you wanted to group the results by the initial ID, use a Left Outer Join, as mentioned previously.

愛上了 2024-07-13 05:53:18

您可能最好使用 Crystal 或 Jasper 等报告工具,如果您胆子大的话,甚至可以使用 XSL-FO。 他们内置了一些东西来专门处理这个问题。 这在原始 SQL 中效果不佳。

如果所有行(标题以及所有详细信息)的格式都相同,那么将其作为存储过程来执行也将非常容易。

我会做什么:将其作为联接进行,这样您将在每一行上都有标题数据,然后使用报告工具进行分组。

You may be best off to use a reporting tool like Crystal or Jasper, or even XSL-FO if you are feeling bold. They have things built in to handle specifically this. This is not something the would work well in raw SQL.

If the format of all of the rows (the headers as well as all of the details) is the same, it would also be pretty easy to do it as a stored procedure.

What I would do: Do it as a join, so you will have the header data on every row, then use a reporting tool to do the grouping.

扶醉桌前 2024-07-13 05:53:18
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

这实际上取决于您需要将数据输出到报告的格式。

如果您可以提供一个示例来说明您希望如何输出,我可能会提供更多帮助。

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

OR if the data is all in the same format you could do.

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

It really depends on the format you require the data in for output to the report.

If you can give a sample of how you would like the output I could probably help more.

喜你已久 2024-07-13 05:53:18

将所有表连接在一起。

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

然后,您需要汇总代码中的列,以按照您认为合适的方式设置报告格式。

Join all of the tables together.

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

Then, you'll want to roll up the columns in code to format your report as you see fit.

2024-07-13 05:53:18

我要做的是在以下查询上打开游标:

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

然后我会并行遍历这些游标,打印结果。 您可以这样做,因为所有内容都以相同的顺序出现。 (请注意,我建议虽然 table1 的主 ID 可能被命名为 id,但它不会在其他表中具有该名称。)

What I would do is open up cursors on the following queries:

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

And then I would walk those cursors in parallel, printing your results. You can do this because all appear in the same order. (Note that I would suggest that while the primary ID for table1 might be named id, it won't have that name in the other tables.)

So尛奶瓶 2024-07-13 05:53:18

所有表格的格式都相同吗? 如果没有,那么您必须有一个可以显示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 并在最后获得单个结果集。 ..

Do all the tables have the same format? If not, then if you have to have a report that can display the n different types of rows. If you are only interested in the same columns then it is easier.

Most databases have some form of dynamic SQL. In that case you can do the following:

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
}

But I mean basically here you are running one query on your main table to get the rows that you need, then running one query for each sub table to get rows that match your main table.

If the report requires the same 2 or 3 columns for each table you could change the select * from tablex to be an insert into and get a single result set at the end...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文