Sql 获取货架上的最后一项名称

Sql 获取货架上的最后一项名称,sql,Sql,我有这张桌子: CREATE TABLE stock (shelf varchar, item_id INT, item_name varchar); 现在我想得到每个架子上最后的物品清单。最后一项是具有最大项\u id的项。我只知道如何获取最后一个id: SELECT shelf, MAX(item_id) FROM stock GROUP BY shelf; 鉴于这些数据: INSERT INTO stock (shelf, item_id, item_name) VALUES (1,

我有这张桌子:

CREATE TABLE stock (shelf varchar, item_id INT, item_name varchar);
现在我想得到每个架子上最后的物品清单。最后一项是具有最大
项\u id
的项。我只知道如何获取最后一个id:

SELECT shelf, MAX(item_id) FROM stock GROUP BY shelf;
鉴于这些数据:

INSERT INTO stock (shelf, item_id, item_name) VALUES (1, 1, 'one');
INSERT INTO stock (shelf, item_id, item_name) VALUES (2, 2, 'two');
INSERT INTO stock (shelf, item_id, item_name) VALUES (1, 3, 'three');
INSERT INTO stock (shelf, item_id, item_name) VALUES (2, 4, 'four');
上面的代码返回:

 2     |   4
 1     |   3
但是我怎样才能得到最后一个项目的名称呢


(最好有一个标准SQL的解决方案,但如果这不可能,我现在就使用Postgres。)

这里有一个
通用的
解决方案,使用
相关子查询
可以在我所知道的每个数据库引擎中工作

select * from stock s
where item_id = (SELECT  MAX(item_id) FROM stock s1 where s1.shelf = s.shelf)

另一种方法是使用
ROW\u NUMBER
这种方法比
相关子查询
方法更有效,但不适用于所有
RDBMS
ex:
Mysql

这里有一个
通用的
解决方案,它使用
相关子查询
在我所知道的每个数据库引擎中都有效

select * from stock s
where item_id = (SELECT  MAX(item_id) FROM stock s1 where s1.shelf = s.shelf)

另一种方法是使用
ROW\u NUMBER
,这种方法比
correlated sub query
方法更有效,但不适用于所有
RDBMS
ex:
Mysql
您可以使用
ROW\u NUMBER
窗口功能:

SELECT shelf, item_id, item_name
FORM   (SELECT shelf, item_id, item_name,
               ROW_NUMBER() OVER (PARTITOIN BY shelf ORDER BY item_id DESC) rn
        FROM   stock)
WHERE  rn = 1

您可以使用
行号
窗口功能:

SELECT shelf, item_id, item_name
FORM   (SELECT shelf, item_id, item_name,
               ROW_NUMBER() OVER (PARTITOIN BY shelf ORDER BY item_id DESC) rn
        FROM   stock)
WHERE  rn = 1

使用子查询。这将适用于所有数据库类型(100%)

SELECT s.*
FROM stock s,
     (SELECT shelf, MAX(item_id) AS last_id FROM stock GROUP BY shelf) sub
WHERE s.shelf = sub.shelf
AND s.item_id = sub.last_id

使用子查询。这将适用于所有数据库类型(100%)

SELECT s.*
FROM stock s,
     (SELECT shelf, MAX(item_id) AS last_id FROM stock GROUP BY shelf) sub
WHERE s.shelf = sub.shelf
AND s.item_id = sub.last_id

有多种方法可以获得结果,我已经在本文中说明了一些方法。@prdp@mureinik建议的方法是一些最好的方法

SELECT B.shelf,B.item_id,A.item_name
FROM stock A
JOIN (SELECT shelf, MAX(item_id) as item_id FROM stock GROUP BY shelf) B ON A.item_id=B.item_id AND A.shelf=B.shelf


SELECT A.shelf,A.item_id,A.item_name
FROM stock A
WHERE item_id = (SELECT  MAX(item_id) FROM stock B where A.shelf = B.shelf)

有多种方法可以获得结果,我已经在本文中说明了一些方法。@prdp@mureinik建议的方法是一些最好的方法

SELECT B.shelf,B.item_id,A.item_name
FROM stock A
JOIN (SELECT shelf, MAX(item_id) as item_id FROM stock GROUP BY shelf) B ON A.item_id=B.item_id AND A.shelf=B.shelf


SELECT A.shelf,A.item_id,A.item_name
FROM stock A
WHERE item_id = (SELECT  MAX(item_id) FROM stock B where A.shelf = B.shelf)

我无法在postgres中使用它,因为它抱怨子查询只能返回一列。如果我们将其转换为SQL-92语法,即在
from
子句中指定联接,而不是在
where
子句中指定联接,则效果很好。我无法在postgres中按编写的方式使用该语法,因为它抱怨子查询只能返回单个列。如果我们将其转换为SQL-92语法,即在
from
子句中指定联接,而不是在
where
子句中指定联接,则效果良好。