将列表与其他多个列表进行比较

时间:2011-11-28 11:45:01

标签: c# asp.net sql sql-server compare

我没有运气寻找解决方案,部分原因是因为我不确定如何最好地解释这个问题!希望我在这里很清楚,但如果没有,请随时询问更多信息。

在顶层: 在我们的数据库中,每个客户可以拥有多项服务。服务单独分配给客户。但是,出于报告目的,我们需要将“群组”服务转换为常见服务组合的“包”。

我有一个包含包定义的数据库 - 一个名为packageServices的表,只是列出每个PackageID以及一个关联的ServiceID。因此,我可以检索每个包的服务列表。

在同一个数据库中,我可以检索特定客户的ServiceID列表。

我想要完成的是比较为该客户检索的ServiceID列表,并查看该组合是否与任何已定义的pacakges(即ServiceID的组合)匹配,如果是,则报告该客户具有哪些软件包

到目前为止,我很难知道从哪里开始比较!我想我需要首先为每个包创建一些serviceIDs列表(而不是我当前的KeyValuePairs(在字典中),每个包有多行?)然后遍历包并将这些服务列表与列表进行比较客户有哪些服务?

这里使用的数据类型可能不是最合适的 - 在很多情况下我指的是'逻辑'列表而不是C#List对象 - 我可以使用适当的数据类型:)

非常感谢任何帮助!

编辑 - 有人建议我在SQL中而不是在我的C#应用​​程序中整理这些信息。这似乎是一个好主意,下面的答案中的一个让我很接近。但是,有一些“业务规则”可以确定包是否是较低包或包本身的“升级”,这使事情变得非常复杂。

我越努力使这项工作越多,我认为我咬的比我能咀嚼的多!我正在尝试来正确设计,以便将来对服务或包​​的任何更改都很容易处理 - 这些更改不太可能,但可能。但是,从我到目前为止看到的选项硬编码会更容易!

编辑2 - 我一直在努力解决这个问题,并建议我为每个包分配一个'权重'和'组'。这些组用于确保客户只能从每个组中获得一个包,并且权重用于确保仅返回“最高”级包。将此与@MarceloCantos的查询结合使用意味着我应该能够从每个组中返回“最高”权重包 - 看起来它可能符合应用程序的要求!

感谢所有迄今为止帮助过的人 - 我很惊讶响应的开始时间和响应的质量。我会试一试,看看我是怎么过的。

2 个答案:

答案 0 :(得分:3)

我建议您不要试图计算客户订阅的软件包(订阅可能不是正确的单词,但您知道我的意思)。我建议您保留单独的记录,指明客户在数据库中订阅的包。每次客户添加新服务时,您都会使用一条消息指示添加服务的事件已发生,并通过使用添加新产品的任何软件包更新该客户的软件包来处理该事件。

答案 1 :(得分:1)

您可以为客户计算服务,然后,对于具有相同服务数量的每个包,计算与客户服务匹配的服务。只有完全匹配才会产生相同的计数。

你可以在一个查询中执行此操作,虽然这是一个相当棘手的问题:

SELECT CustomerID, PackageID
  FROM (SELECT CustomerID, COUNT(*) AS qty
          FROM customerServices
         GROUP BY CustomerID
       ) cs
  JOIN (SELECT PackageID, COUNT(*) AS qty
          FROM packageServices
         GROUP BY PackageID
       ) ps ON cs.qty = ps.qty
 WHERE (SELECT COUNT(*)
          FROM customerServices cs2
          JOIN packageServices ps2 ON cs2.ServiceID = ps2.ServiceID
         WHERE cs2.CustomerID = cs.CustomerID
           AND ps2.PackageID = ps.PackageID
       ) = ps.qty

编辑:也许我误解了这个问题。如果要查找包含客户服务的子集的软件包,可以改为:

 ...
       ) ps ON cs.qty >= ps.qty -- Change the test
 WHERE (SELECT COUNT(*)
          FROM customerServices cs2
          JOIN packageServices ps2 ON cs2.ServiceID = ps2.ServiceID
         WHERE cs2.CustomerID = cs.CustomerID
           AND ps2.PackageID = ps.PackageID
       ) = ps.qty

编辑2:我更改了第二种情况的逻辑,以利用这样一个事实,即如果两个集合的交集与较小集合的大小相同,那么较小的集合是该集合的一个子集。大。