【问题标题】:Returning data in non tabular form from SQL server从 SQL Server 以非表格形式返回数据
【发布时间】:2021-08-20 06:16:40
【问题描述】:

请原谅我这个模糊的标题,但我找不到更合适的词来总结我的问题。

在数据库中有两个表,我想合并并从中检索数据:

Id   Name     Description               Id       Batch    Quantity
1    Item_A     ....                     1         1A       25
2    Item_B     ....                     1         1B       25
3    Item_C     ....                     1         1C       50
.                                        1         1D       50
.                                        2         2A       21
                                         .          .        .
                                         .          .        .

我想将第二个表中的数据与其对应的第一个表中的 Id 结合起来, 即为批次项目提供适当的名称和描述。

一个简单的连接确实为我提供了我想要的数据,但连接这两个表会产生一个大表,其中每个具有相同 ID 的批次都会重复描述列,即使相同 Id 的只有一个描述数据会足够了。

有没有什么办法可以将Name和Description的数据组合到第二张表中对应的Id值,但又不会产生冗余数据,其中Name和相当长的Description列不重复同一个ID?

我尝试过的一个解决方案是分别检索这两个表,但通过按照 Id 以相同的顺序进行排序。这样我就可以使用简单的映射函数来创建一个像这样的伪对象:

Main{
   List<Item> Items
}
Item{
   string Name
   string Description
   List<Quantity> Quantities
}
Quantity{
    string Batch
    int Quantity
}

但是,这会破坏两种语言的数据操作步骤,并使代码变得复杂且难以理解。

最好,我想一次检索所有项目的数据(执行一次存储过程)。有人能证明这是一个好方法吗?

【问题讨论】:

  • 如果我理解正确,您所要求的是通常由前端执行的操作,而不是查询本身。要么拉取冗余数据,要么在 2 个查询中拉取数据以避免重复数据。同时添加您当前的 SQL。
  • 您可以从连接表中选择您想要的列。
  • @DaleK 我正在使用 sql-server 2014。我想知道是否可以在数据库本身中完成类似的操作,或者如果没有,是否有更好的方法。
  • @j1mbl3s 我想要所有的列,(因为我想要每个 ID 至少有一个名称和描述)但想避免冗余数据
  • 更好的方法是不在数据库中进行。

标签: sql-server database tsql join


【解决方案1】:

您可以尝试使用 XML。

这是在 MS SQL Server 中生成父/子一对多 XML 的方法。

SQL

-- DDL and sample data population, start
DECLARE @parent TABLE (ID INT PRIMARY KEY, ItemName VARCHAR(30));
INSERT INTO @parent (ID, ItemName) VALUES
(1, 'Item_A'),
(2, 'Item_B');

DECLARE @child TABLE (ID INT IDENTITY PRIMARY KEY, ParentID INT, Batch CHAR(2), Quantity INT);
INSERT INTO @child (ParentID,  Batch,  Quantity) VALUES
(1, '1A', 25),
(1, '1B', 25),
(1, '1C', 50),
(2, '1D', 50),
(2, '2A', 21);
-- DDL and sample data population, end

SELECT p.*
    , (
    SELECT c.* 
    FROM @child AS c
    WHERE c.ParentID = p.ID
    FOR XML PATH('r'), TYPE, ROOT('child')
)    
FROM @parent AS p
FOR XML PATH('r'), TYPE, ROOT('root');

输出

<root>
  <r>
    <ID>1</ID>
    <ItemName>Item_A</ItemName>
    <child>
      <r>
        <ID>1</ID>
        <ParentID>1</ParentID>
        <Batch>1A</Batch>
        <Quantity>25</Quantity>
      </r>
      <r>
        <ID>2</ID>
        <ParentID>1</ParentID>
        <Batch>1B</Batch>
        <Quantity>25</Quantity>
      </r>
      <r>
        <ID>3</ID>
        <ParentID>1</ParentID>
        <Batch>1C</Batch>
        <Quantity>50</Quantity>
      </r>
    </child>
  </r>
  <r>
    <ID>2</ID>
    <ItemName>Item_B</ItemName>
    <child>
      <r>
        <ID>4</ID>
        <ParentID>2</ParentID>
        <Batch>1D</Batch>
        <Quantity>50</Quantity>
      </r>
      <r>
        <ID>5</ID>
        <ParentID>2</ParentID>
        <Batch>2A</Batch>
        <Quantity>21</Quantity>
      </r>
    </child>
  </r>
</root>

【讨论】:

  • 感谢您的想法。我会尝试将此应用到我的解决方案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
相关资源
最近更新 更多