SQL:搜索以查找列表是否与其他项的完整列表匹配

时间:2013-12-29 05:06:40

标签: sql database sqlite

我不是SQL专家,也不确定如何正确解释这个问题...更不用说如何正确构建我的数据库来解决这个问题...所以我猜这就是我在这里的原因。希望得到一些建议。

假设我拥有30个“项目”。然后,还有一个包含1000个小部件的列表。每个都由X个“项目”组成。

我需要找出我可以用我的项目制作哪些小部件,还需要找出构建数据以有效查找结果的最佳方法。

我非常感谢您提供最佳方法的任何帮助。谢谢大家!

1 个答案:

答案 0 :(得分:2)

让我们从数据结构开始。通常的方法是使用两个表widgetsitems来表示小部件和项目的属性。每个表都有一个主键id

您需要将每个小部件映射到它所构成的项目。我们使用的表格widgets_items_map包含两个foreign keyswidget_iditem_id。此表的每一行都规定id中引用widgets_items_map.widget_id的窗口小部件使用widgets_items_map.item_id引用的项目。这是一个经典的Many to Many关系实现。

您可以考虑使用users_items_map表来存储哪个用户拥有哪个项目。我们使用具有两个外键的类似模型user_iditem_id

让我们深入研究。

要知道哪些项目构成给定的小部件(标识为[[WIDGET ID]]),您可以使用简单的WHERE clause

SELECT wmap.item_id
    FROM widgets_items_map AS wmap
    WHERE wmap.widget_id = [[WIDGET ID]]

这将为您提供项目ID列表,带有items表格的简单JOIN将获取获取其余数据的技巧。

同样,要获取用户(标识为[[USER ID]])的项目列表:

SELECT umap.item_id
    FROM users_items_map AS umap
    WHERE umap.user_id = [[USER ID]]

使用NOT IN criterionsubquery,您可以获取用户构建每个小部件的缺失项列表:

SELECT wmap.item_id
    FROM widgets_items_map AS wmap
    WHERE wmap.item_id NOT IN (
        -- Get the items held by user [[USER ID]]
        SELECT umap.item_id
            FROM users_items_map AS umap
            WHERE umap.user_id = [[USER ID]]
    )

添加GROUP BY将获取此用户无法构建的小部件列表:

SELECT wmap.widget_id
    FROM widgets_items_map AS wmap
    WHERE wmap.item_id NOT IN (
        -- Get the items held by user [[USER ID]]
        SELECT umap.item_id
            FROM users_items_map AS umap
            WHERE umap.user_id = [[USER ID]]
    )
    GROUP BY wmap.widget_id

我们快到了。您只需将此无法构建的小部件列表减去完整的小部件列表即可获取可构建小部件列表:

SELECT w.id
    FROM widgets AS w
    WHERE w.id NOT IN (
        -- Get the list of widgets that cannot be built using the item list provided
        -- (i.e. those of user [[USER  ID]]
        SELECT wmap.widget_id
            FROM widgets_items_map AS wmap
            WHERE wmap.item_id NOT IN (
                -- Get the items held by user [[USER ID]]
                SELECT umap.item_id
                    FROM users_items_map AS umap
                    WHERE umap.user_id = [[USER ID]]
            )
            GROUP BY wmap.widget_id
    )

这些只是帮助您入门的基础知识。上述请求和模型需要稍微调整才能处理,比方说,你持有的每件物品的数量。