【问题标题】:SQL joins and logicSQL 连接和逻辑
【发布时间】:2010-12-23 08:00:38
【问题描述】:

我正在使用我在 C# 中设计的 SharePoint Web 部件。我需要查询 SQL Server 2005 数据库以返回与用户选择的特定客户相关联的机器名称。

问题在于有不同类型的机器,并且名称本身存储在其他几个表中。这是与此问题相关的结构:

我有一个表“customerInfo”,其中包含每个客户的 ID 和名称。 ID 是主键。

“machineIDs”表将客户 ID 链接到相应的机器 ID。机器 ID 是主键。

我有两个表用于两种类型的机器,“machine1”和“machine2”。 machine1 包含机器本身的名称,但 machine2 仅包含机器类型的 ID。对于这两个表,机器 ID 都是主键。

然后我有一个表“specialtyMachine”。此表包含机器的名称和该类型机器的 ID。这里的主键是一个类型ID,它标识机器的类型,而机器ID标识具体的机器。

我需要做的是从 machine1 和 specialMachine 中提取机器名称,只给定客户 ID。我不确定是否可以直接在查询中使用复杂的联接来执行此操作,或者我是否需要在 Web 部件中应用逻辑来将这些信息汇总在一起。

我还想知道如何从通用模型的角度来考虑这个问题。我希望能够认识到这一点并在未来普遍应用它,因为我确信这是一个我还没有处理过的相当普遍的问题。谢谢。

【问题讨论】:

  • 您能否添加一些我们需要处理此类查询的 mote 结构/模式?
  • 我刚刚在架构中添加了更多信息。我认为它现在包含所有相关信息。

标签: c# sql sharepoint join web-parts


【解决方案1】:

根据您的新架构信息,我猜这就是您想要的:

select *
from customerinfo c
left join machineids mids on c.customerid = mids.customerid
left join machine1 m1 on mids.machineid = m1.machineid
left join spcialtymachine sm on mids.machineid = sm.machineid -- or m1.machineid = sm.machineid
left join machine2 m2 on sm.typeid = m2.typeid

注意:如果您在以@customerid 作为参数的存储过程中使用它,您可以在末尾添加where c.customerid = @customerid

【讨论】:

  • 这很接近了。实际上,它确实提取了我需要的所有行,并且只提取了我需要的行。但是,它不会填充“sm”(使用您的指定)字段。这是因为 sm.machineid 和 mids.machineid 不是等价的。每个客户都有一定数量的机器(mids.machineid)。只有某些机器具有 sm.machineid,然后将它们链接到 specialmachine 表。所以这两个 machineid 是不同的,这让我不知道如何返回我需要的字段。
  • 非常感谢。您之前的查询对于让我更接近这个查询和理解内部连接的工作方式都非常有帮助。我会在几分钟后下班,但我会在星期一早上把这个拿回来。再次感谢。
  • 好的...这是否意味着 sm.machineid 是 customerinfo (或其他表之一)中的不同字段,或者只是 sm.machineid 具有所有 machineid 的子集。如果它是一个子集,这将正常工作。如果它是不同的外部键字段,我需要知道名称。如果某人 machineids 在一个表中而其他人在另一个表中,它也会显示为多行。那么你需要做一些分组(不用担心,这并不难)。
  • 是的,sm.machineid和mids.machineid是两个不同的ID; sm.machineid 不是 mids.machineid 的子集。例如,假设我有一个客户 ID 为“1001”的客户。例如,在 mids 表中,它们将具有三个不同的机器 ID:“5024”、“6708”和“9699”。对于“5204”和“6708”,我可以简单地从 machine1.machinename 中提取相应的名称。但是,对于“9699”,该产品的信息在 machine2 中,它没有机器名称,而是不同的机器 ID(比如说“192”)。这会将其链接到 sm,其中包含我需要使用的名称。
  • 我将此标记为答案。正如我所说,这会返回我需要的所有行,并且只返回我需要的行;根据我的架构稍作修改,我能够添加另一个 LEFT JOIN 并仅使用客户 ID 从 sm 表中提取附加信息。谢谢!
【解决方案2】:

您想合并两个查询。

SELECT c.ID, m1.Name
FROM customerinfo AS c
JOIN machine1 AS m1
ON m1.customerinfoID = c.ID
WHERE c.ID = @customerID

UNION ALL
SELECT c.ID, sm.Name
FROM customerinfo AS c
JOIN machine2 AS m2
ON m2.customerinfoID = c.ID
JOIN specialtyMachine AS sm
ON sm.TypeID = m2.TypeID
WHERE c.ID = @customerID

【讨论】:

    【解决方案3】:

    您的查询是否会传入客户名称或客户 ID 并期望得到结果?

    CustomerInfo 和 Machine1 之间是否存在人行横道表,或者 Machine1 是否有返回 CustomerInfo.Id 的 FK? Machine2 的同样问题

    【讨论】:

    • 我更新了架构以显示将客户 ID 链接到各自机器的表。查询只会传入客户 ID。
    【解决方案4】:

    您的数据模型听起来有点奇怪,但据我所知没有通用模型,您所说的是标准关系数据库。

    要进行复杂的查询,只需以模块化方式创建查询的不同部分,如下所示(如果我对键的位置有误,那么模块化方式将使您可以轻松修改以供您使用。)

    首先机器映射看起来像这样:

    Select m2.mid as mID, m1.name as mName
    from specialtyMachine sm
    left join machine2 m2 on sm.mid = m2.mid 
    left join machine1 m1 on sm.machinename = m1.machinename
    

    您可以运行并测试它以查看机器到 id 的映射。

    现在我们加入客户信息:

    select * 
    from customerinfo c
    left join 
    (
       Select m2.mid as mID, m1.name as mName
       from specialtyMachine sm
       left join machine2 m2 on sm.mid = m2.mid 
       left join machine1 m1 on sm.machinename = m1.machinename
    ) t on c.mid = t.mid
    

    这可以正常工作(并且有利于测试您是否拥有正确的关系),但不好,因为子查询是针对外部查询中的每一行执行的,最好像这样“展开”它

    select * 
    from customerinfo c
       left join machine2 m2 on c.mid = m2.mid 
       left joint specialtyMachine sm on m2.mid = sm.mid
       left join machine1 m1 on sm.machinename = m1.machinename
    

    警告:我没有测试这个,可能有错别字。

    【讨论】:

    • 数据模型有点奇怪,但技术上是3NF。业务数据让它有点混乱;虽然每台机器都有一个唯一的标识符,但一种类型的机器用一个唯一的名称表示,而另一种机器用一个唯一的类型表示。为了用户简单起见,我必须给他们这些名称,而不是我们的数据库引用他们的唯一标识符。
    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 2013-04-26
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多