【问题标题】:Filter with SQL Server by Group ID按组 ID 使用 SQL Server 过滤
【发布时间】:2021-12-31 11:54:56
【问题描述】:

我有两个表,我需要按过滤器 id 过滤数据,这取决于与过滤器组 id 的关系。

例如我有这两个表:

表 1:

ItemID FilterID
3 122
3 123
3 4
17 123

表 2:

FilterID FilterGroupID
122 5
123 5
4 1
  • 如果我按过滤器 id = 123 搜索,则需要返回具有此过滤器的所有项目 ID。
  • 如果我搜索两个或多个具有不同组 ID 的不同过滤器 ID,我只需要获取具有所有过滤器 ID 和组 ID 的项目 ID。

期望的输出:

  • 第一个输入:123 -> 返回项目 ID = 3 和项目 ID = 17
  • 第二个输入:123,4 -> 返回项 id = 3,因为过滤器 id 123 属于组 id 5,过滤器 id 4 属于组 id 1,并且项 id 3 是唯一具有这两个过滤器的项。李>
  • 第三个输入:122,123 -> 返回项目 id =3 和项目 id = 17,因为这两个过滤器 id 属于同一个组。

我对这个查询有点迷茫,很高兴能得到一些帮助。

我会尽量简化它:假设我们有大小的组过滤器和颜色的组过滤器。如果我按尺寸 S 或 M 过滤,则我需要获取所有具有此尺寸的物品。如果我想添加像蓝色这样的颜色,那么答案将通过以下方式削减结果:尺寸为 S 或 M 和颜色为蓝色的项目。所以来自不同组的过滤器可能会削减一些结果

【问题讨论】:

  • 您能否以格式化的形式分享输出和示例数据。目前还很难理解
  • 我不明白Table2FilterGroupID 与这个问题有什么关系。实际上,您只需要在Table1 和您的过滤器列表之间进行关系划分。他们属于哪个组是无关紧要的

标签: sql sql-server sql-server-2008 subquery


【解决方案1】:

您似乎希望在您的过滤器输入中从每个 FilterGroupID 中获取每个具有至少一个 匹配过滤器的ItemID。所以在每个组内你有or逻辑,在组之间你有and逻辑

如果您将输入存储在表变量或表值参数中,那么您可以使用正常的关系除法技术。

这就变成了Relational Division With Remainder的问题,有多个除数。

有很多方法可以切蛋糕。这是一种选择

  • 将过滤器输入加入组,以获取每个过滤器的组 ID
  • 使用DENSE_RANKMAX 的组合来获得不同组的总数(你不能在窗口函数中使用COUNT(DISTINCT,所以我们需要破解它)
    • 您可以更改此步骤以使用子查询而不是窗口函数。它可能更快或更慢
  • 加入主表,并过滤掉所有不同组的总数与主总数不同的ItemIDs
SELECT
  t1.ItemID
FROM (
    SELECT *,
      TotalGroups = MAX(dr) OVER ()
    FROM (
      SELECT
        fi.FilterID,
        t2.FilterGroupID,
        dr = DENSE_RANK() OVER (ORDER BY t2.FilterGroupID)
      FROM @Filters fi
      JOIN Table2 t2 ON t2.FilterID = fI.FilterID
    ) fi
) fi
JOIN Table1 t1 ON t1.FilterID = fi.FilterID
GROUP BY
  t1.ItemID
HAVING COUNT(DISTINCT FilterGroupID) = MAX(fi.TotalGroups);

db<>fiddle

【讨论】:

  • 组 id 是相关的,以便了解是否需要添加项目,因为它们通过相同的过滤器与相同的组过滤,或者不同的组是否只接受所有组中存在的项目。基本上,查询应该说:添加所有具有相同组中存在过滤器的项目或将它们从组中删除是不同的,并且只取那些住在所有组中的人。我希望这能更好地解释我的情况。你也可以看看我的例子吗?
  • 我会尽量简化它:假设我们有大小的组过滤器和颜色的组过滤器。如果我按尺寸 S 或 M 过滤,则我需要获取所有具有此尺寸的物品。如果我想添加像蓝色这样的颜色,那么答案将通过以下方式削减结果:尺寸为 S 或 M 且颜色为蓝色的项目。所以来自不同组的过滤器可能会削减一些结果
  • 啊我想我明白了:所以每个项目必须至少匹配每个过滤器组中的一个?每个过滤器组必须至少匹配一次,但不是每个过滤器?
  • 几乎,如果我得到的输入(过滤器ID)来自不同的组,那么项目必须在所有这个组和过滤器中(基本上使用组ID的“和”语句),否则(过滤器如果输入来自同一组)通过过滤器ID获取所有项目(“或”过滤器ID声明)
  • 因此,如果您的过滤器列表是“S 码、M 码、蓝色、橙色”,您希望项目的尺寸为 S M、以及 蓝色还是橙色?所以在每个组内你有or逻辑,在组之间你有and逻辑?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多