根据特定字段中的值选择多行中的值

时间:2014-10-14 13:13:08

标签: sql ms-access rows

我的表中包含列出对象类型的行以及可以在其上找到的货架,如下所示:

1,   wrench,   shelf1
2,   wrench,   shelf2
3,   hammer,   shelf2
4,   hammer,   shelf3
5,   pliers,   shelf1
6,   nails,   shelf3
7,   nails,   shelf4

我正在尝试决定如何创建一个查询,该查询将返回可在shelf1上找到但在shelf2上找不到的任何对象。

  • 在这个例子中,我希望返回“钳子”,因为它已打开 shelf1但不在shelf2上。
  • 一个物品可能在许多架子上。
  • 不应退回货架3和4上的物品(钉子)。

我知道每个人都喜欢SO上的代码,但我不会在工作几天,而且我没有尝试过我已经做过的失败。我确实发现Access没有EXCEPT,并且不支持查询别名,因此我可以执行查询并针对结果运行另一个查询。我无法使用INSERT INTO将临时表写入现有数据库。

非常感谢任何有关如何入门的建议!

3 个答案:

答案 0 :(得分:2)

您可以为Shelf 1和Shelf 2创建子查询。然后将Shelf1子查询LEFT JOIN连接到Product名称上的Shelf2子查询。然后只记录Shelf2为空的记录。

SELECT
    Shelf1.*
FROM
    (SELECT [ID], [Product], [Location] FROM <table> WHERE [location]="Shelf1") as Shelf1
    LEFT OUTER JOIN
        (SELECT [Product] FROM <table> WHERE [location]="Shelf2") as Shelf2 ON
            Shelf1.Product = Shelf2.Product
WHERE
    Shelf2.Product IS NULL

答案 1 :(得分:1)

如果您只需要产品名称,则可以使用GROUP BY/HAVING

SELECT  Name
FROM    T
WHERE   Shelf IN ('shelf1', 'shelf2')
GROUP BY Name
HAVING SUM(IIF(Shelf = 'Shelf2', 1, 0)) = 0;

只使用条件和来排除任何在shelf2上有记录的东西。

最后,为了略微扩展JNevill的答案,子查询不是必需的,你可以用稍微简单的方式做到这一点:

SELECT  t1.ID, t1.Name, t1.Shelf
FROM    T AS t1
        LEFT JOIN T AS t2
            ON t.Name = t2.Name
            AND t2.Shelf = 'Shelf2'
WHERE   t1.Shelf = 'Shelf1'
AND     t2.ID IS NULL;

答案 2 :(得分:1)

以下是该问题的简单查询。验证shelf1中的对象是否不在shelf2中所有对象的表中

SELECT *
    FROM Table
    WHERE shelf = 'shelf1' AND object NOT IN 
    (SELECT object FROM Table WHERE shelf='shelf2')