【问题标题】:SQL Server multiple many-to-many join querySQL Server 多对多连接查询
【发布时间】:2010-10-11 14:14:36
【问题描述】:

我目前有一个主表,其中多个其他表通过多对多连接(使用连接表)与之关联。使用此数据库的应用程序需要具有搜索功能,该功能将打印出匹配特定条件的多行,包括连接表中的所有值。连接表中的值也需要是链接,以便能够搜索与该值匹配的所有其他行。我想弄清楚如何在不对数据库征税的情况下做到这一点。

这是一个表结构的例子

**Metrics (Main Table)** 
MetricID (pk) 
Metric

**Domains (ValueList Table)** 
DomainID (pk) 
Domain

**MetricsDomains (Join Table)** 
MetricsDomainsID (pk) 
MetricID (fk) 
DomainID (fk)

**MetricTypes (ValueList Table)** 
MetricTypeID (pk) 
MetricType

**MetricsMetricTypes (Join Table)** 
MetricMetricTypesID (pk) 
MetricID (fk) 
MetricTypeID (fk)

**Studies (ValueList Table)** 
StudyID (pk) 
Study

**MetricsStudies (Join Table)** 
MetricsStudiesID (pk) 
MetricID (fk) 
StudyID (fk)

当有人按各种条件搜索指标时,他们应该以表格格式获得输出,如下所示:

Metric1 | Description | Study1, Study2, Study3 | MetricType1, MetricType2 | Domain1, Domain2
Metric2 | Description | Study5, Study2, Study4 | MetricType2, MetricType3 | Domain5, Domain9

指标将是指标完整描述的链接。但是,此外,Study(即 Study 1、Study 2、Study 3 等)和 MetricTypes(MetricType1、Metric2 等)和 Domains(Domain1、Domain 2 等)也应该是链接,即单击后,将对包含该研究、类型或域的所有其他指标执行新搜索。这使我相信除了文本之外,我还需要研究、类型或域的主键才能放置在 href 中。

无论如何,考虑到一次搜索可能会返回 20 多个指标,我需要找出一种编写优化查询以返回多个多对多连接结果的好方法。我知道在一个查询中连接所有这些表通常会导致所有连接的笛卡尔积,但我不确定是否有另一种方法可以解决它。我还阅读了一种方法,我可以使用以下方法将多对多结果作为逗号分隔的列表返回到字段中:

SELECT m.MetricID, Description, 
    STUFF((
    SELECT ', ' + s.Study
    FROM Studies s, Metrics_Studies ms 
    WHERE s.StudyID = ms.StudyID AND ms.MetricID = m.MetricID
    ORDER BY s.Study
    FOR XML PATH('')
    ),1,1,'') as Study, 
FROM Metrics m 
WHERE Metric_PK = 13

但是,我不确定这种方法对性能的影响,或者它是否真的能得到我想要的东西,因为我认为我可能还需要 Study 的主键。

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • MetricsMetricTypes 中的最后一个字段是否应该是 MetricTypeID 而不是 DomainID?
  • 在您的连接表(即 MetricsDomains)中,您真的需要一个单独的 PK(MetricsDomainsID),​​还是可以将其组合成两个 FK? (度量 ID、域 ID)。这意味着您只能使用每种组合中的一种,但无论如何感觉都是对的。
  • @Mark 你是对的。我已经在原始问题中修复了它。
  • @Paul 我可以做到。每个组合应该只有一个。不知道这是否会影响原始问题:-/

标签: sql sql-server join many-to-many


【解决方案1】:

我建议先使用您的多连接来执行此操作 - 只有这样您才能知道性能是否足够好。与往常一样,您必须提防过早的优化。一旦您的查询针对您的规范化模型正确运行,您可以检查查询计划等。这可能会突出显示您需要展平一些连接,如果是这种情况,您可能必须将数据存储在两个不同的格式,一种用于报告/一种用于搜索,等等。但第一件事是查看性能是否可以开箱即用。希望这会有所帮助。

【讨论】:

  • 谢谢保罗。到目前为止,由于我需要继续使用这个应用程序,我一直在使用我上面发布的子查询方法的变体(尽管我消除了它周围的 STUFF() 函数以节省一些数据库处理,因为我可以消除前导逗号通过应用程序内的后处理)。这是你的建议吗?到目前为止,查询处理时间还没有达到百分之一秒,所以我认为这不是问题。我只是想知道是否有更清洁/更好的方法来解决它。
  • @Kirsen:是的,就是这样 - 得到一些干净的东西(你明白)。就像您说的那样,这使您可以继续申请。只有在需要时,才重新访问以提高性能。在您开发应用程序时,其他一些事情可能会触发数据模型的更改,这会否定您所做的任何优化,或者提供一种更简单的方法来优化代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多