2

我有三张桌子。

  • 表数据包含来自“data.txt”文件的各个部分的数据。
  • 表限制包含来自“limits.txt”文件的数据表的限制。
  • 表格文件是上面每个单独的 .txt 文件的列表。

所以“文件”表看起来像这样。如您所见,它是存在的每个文件的列表。LimitsA 文件将包含每个 A 类型数据文件的限制。

ID  File_Name  Type  Sub-Type
1   DataA_10   A     10
2   DataA_20   A     20
3   DataA_30   A     30
4   LimitsA    A     NONE
5   DataB_10   B     10
6   DataB_20   B     20
7   LimitsB    B     NONE

“数据”表如下所示。File_ID 是“文件”表中的外键。具体来说,这将是上面 DataA_10 的数据:

ID  File_ID  Dat1  Dat2  Dat3... Dat20
1   1        50    52    53 
2   1        12    43    52 
3   1        32    42    62 

“限制”表如下所示。File_ID 是“文件”表中的外键。具体来说,这将是上述 LimitsA 的数据:

ID  File_ID  Sub-Type  Lim1  Lim2
1   4        10        40    60    
2   4        20        20    30    
3   4        30        10    20    

所以我想要做的是将“限制”表中的正确限制加入相应“数据”表中的数据。DataA_10 的每一行将具有来自 LimitsA 表的“40”和“60”限制。不幸的是,没有办法直接将限制表链接到数据表。做到这一点的唯一方法是回顾文件表并看到 LimitsA 和 DataA_10 属于 A 类型。一旦我将这两者链接在一起,我就需要专门只获取 Sub-Type 10 的限制。

最后,我想要一个看起来像这样的结果。

结果:

ID  File_ID  Dat1  Dat2  Dat3... Dat20  Lim1  Lim2
1   1        50    52    53             40    60
2   1        12    43    52             40    60
3   1        32    42    62             40    60

我希望这足够清楚,可以理解。在我看来,这似乎是一个加入 2 个以上表的问题,但我一直无法在网上找到合适的解决方案。如果您有解决方案或任何建议,将不胜感激。

4

1 回答 1

1

您的“文件”表实际上是 2 个已合并的独立(但相关)概念。如果您使用子查询将它们分开,您将更容易进行连接。请注意,像这样加入不是最有效的方法,但同样也不是给定的模式......

SELECT Data.*, Limits.Lim1, Limits.Lim2
FROM (SELECT * FROM Files WHERE SubType IS NOT NULL) DataFiles
JOIN (SELECT * FROM Files WHERE SubType IS NULL) LimitFiles
  ON LimitFiles.Type = DataFiles.Type
JOIN Data 
  ON DataFiles.ID = Data.File_ID
JOIN Limits
  ON LimitFiles.ID = Limits.File_ID
  AND DataFiles.SubType = Limits.SubType
ORDER BY Data.File_ID

更新

更具体地说明如何改进架构:目前,该Files表没有明确的方法来区分数据和限制文件条目。除此之外,数据条目没有指向单个限制文件条目的明确链接。虽然这两个都可以在上面的 SQL 中计算出来,但是这样的逻辑可能无法很好地与查询优化器配合使用,并且肯定不能保证您需要的 Data-Limit 链接。

考虑以下选项:

  • 不是通过链接到“限制”文件Type,而是直接链接到限制条目Id。在该链接上设置外键以确保预期的限制条目可用。
  • 将“限制”条目与“数据”条目分开,方法是将它们放在单独的表中。
  • 在外键上创建索引。为此,为所有外键添加索引 - 默认情况下 SQL Server 不这样做。

其中,我认为有一个外键是必不可少的,而其他的则是适度的改进。

于 2012-11-19T17:11:20.523 回答