【问题标题】:Selecting multiple tables from single table by distinct column value in stored procedure通过存储过程中的不同列值从单个表中选择多个表
【发布时间】:2009-07-27 20:31:27
【问题描述】:

我有一个难题需要解决,我正在努力寻找一个好的解决方案。我正在使用 MS SQL server 2005,并给出了一个表,其中 uniqueidentifier 列包含服务器上其他信息的数据键。我需要做的是选择此数据表中的每一行(来自 ASP.NET 的存储过程),但根据这一列分为表。例如,来自

------------------------------------
MyID    |  MyOtherData
------------------------------------
 4         asdf
 4         test
 3         qwerty
 2         morestuff

我希望返回以下三个表:

------------------------------------
MyID    |  MyOtherData
------------------------------------
 4         asdf
 4         test

------------------------------------
MyID    |  MyOtherData
------------------------------------
 3         qwerty

------------------------------------
MyID    |  MyOtherData
------------------------------------
 2         morestuff

如果我事先不知道会有多少个唯一的 MyID 值,我该如何解决这个问题?

【问题讨论】:

  • 我真正的问题是为什么?这最终可能会产生多个结果集......并且可能非常麻烦。
  • 我假设他的意思是他指的是“表格”的结果集,但我和米切尔在一起。与一次性退货相比,这有什么好处?

标签: asp.net sql-server sql-server-2005 tsql stored-procedures


【解决方案1】:

最好不要在 Proc 中执行此操作,而是在客户端代码中执行此操作。

  1. 编写一个查询/过程,返回 不同的 MyID 值(SELECT MYID 与 MyTable 不同)
  2. 在您的应用程序中,循环遍历每个 选择值并调用另一个过程 接受一个 MyID 值并返回 该值的记录集。 (从 MyTable Where MyID=? 中选择 MyOtherData)

【讨论】:

  • 取决于生成的结果集数量。在客户端进行这样的循环让我想起了我所见过的性能问题,即渲染单个网页需要 200 到 800 次往返。
  • 确实如此。在长时间锁定资源的单一查询和一系列耗时打开和关闭连接的短查询之间存在一定的权衡(尽管池应该涵盖这一点)。理想的解决方案听起来像是重新设计数据库或应用程序逻辑以避免整个问题。
【解决方案2】:

这里想到的唯一一件事,这不是一个好主意....但是会创建一个光标,它适用于一个查询

选择不同的 MyId 来自我的表

然后,光标的每次迭代都会进行相应的选择...

【讨论】:

    【解决方案3】:

    我认为您应该尝试重新考虑您的方法,因为我认为它不会具有很强的可扩展性,而且我认为从长远来看,尝试找到实现这一目标的方法是不值得的。

    相反,您能否不返回一个按 MyID 排序的结果集,然后在 .NET 中以不同方式处理该结果集?

    【讨论】:

      【解决方案4】:

      您可以创建一个循环结构,循环访问主表 ID 的子集,以便为每组表生成一个单独的结果集。这很丑陋,但希望这只是您想要摆脱并希望永远不必再处理的一些临时事情。

      DECLARE @Entities TABLE
      (
           ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
           MyID int,
           MyOtherData varchar(100)
      )
      
      INSERT INTO @Entities (MyID, MyOtherData)
      SELECT MyID, MyOtherData
      FROM TheMainTable
      ORDER BY MyID, MyOtherData
      
      DECLARE @Count int
      DECLARE @Max int
      
      SET @Count = 1
      SELECT @Max = COUNT(ID) FROM @Entities
      
      DECLARE @MyID_Current int
      
      WHILE (@Count <= @Max)
      BEGIN
      
           SELECT @MyID_Current = MyID
           FROM @Entities
           WHERE ID = @Count
      
           -- Output each individual result set.
           SELECT MyID, MyOtherData
           FROM @Entities
           WHERE MyID = @MyID_Current
      
           SET @Count = @Count + 1
      
      END
      

      对于更丑陋的事情,您可以在每次迭代时在数据库中创建或选择一个新的、唯一命名的表,而不是只生成单独的结果集,并将特定的 MyID 记录插入到该表中。

      【讨论】:

        【解决方案5】:
        DECLARE @Entities TABLE
        (
         ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
         MyID int,
         MyOtherData varchar(100)
        )
        
        INSERT INTO @Entities (MyID, MyOtherData)
        SELECT MyID, MyOtherData
        FROM TheMainTable
        ORDER BY MyID, MyOtherData
        
        DECLARE @Count int
        DECLARE @Max int
        
        SET @Count = 1
        SELECT @Max = COUNT(ID) FROM @Entities
        
        DECLARE @MyID_Current int
        
        WHILE (@Count <= @Max)
        BEGIN
        
         SELECT @MyID_Current = MyID
         FROM @Entities
         WHERE ID = @Count
        
         -- Output each individual result set.
         SELECT MyID, MyOtherData
         FROM @Entities
         WHERE MyID = @MyID_Current
        
         SET @Count = @Count + 1
        
        END
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-05
          • 1970-01-01
          • 1970-01-01
          • 2021-11-25
          • 2017-03-25
          • 2017-12-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多