我有一个表产品:
id | owner_id | last_activity | box_id
------------------------------------
1 | 2 | 12/19/2014 | null
2 | 2 | 12/13/2014 | null
3 | 2 | 08/11/2014 | null
4 | 2 | 12/11/2014 | 99
5 | 2 | null | 99
6 | 2 | 12/15/2014 | 99
7 | 2 | null | 105
8 | 2 | null | 105
9 | 2 | null | 105
我唯一的变量是 owner_id 。 我需要选择用户的所有产品,但如果产品在一个盒子中,那么只应该选择最新的产品。
owner = 2的示例输出如下:
id | owner_id | last_activity | box_id
------------------------------------
1 | 2 | 12/19/2014 | null
2 | 2 | 12/13/2014 | null
3 | 2 | 08/11/2014 | null
6 | 2 | 12/15/2014 | 99
7 | 2 | null | 105
我无法找到从盒子中选择最新产品的方法。
我当前的查询,它不会返回正确的值,但可以执行:
SELECT p.* FROM product p
WHERE p.owner_id = 2
AND (
p.box IS NULL
OR (
p.box IS NOT NULL
AND
p.id = ( SELECT MAX(pp.id) FROM product pp
WHERE pp.box_id = p.box_id )
)
我尝试过日期:
SELECT p.* FROM product p
WHERE p.owner_id = 2
AND (
p.box IS NULL
OR (
p.box IS NOT NULL
AND
p.id = ( SELECT * FROM (
SELECT pp.id FROM product pp
WHERE pp.box_id = p.box_id
ORDER BY last_activity desc
) WHERE rownum = 1
)
)
哪个错误: p.box_id 未定义,因为它在第二个子查询中。
您有什么想法我该如何解决?
答案 0 :(得分:0)
使用存在
SELECT
p.*
FROM
product p
WHERE
p.owner_id = 2 AND
( p.box IS NULL OR
(
p.box IS NOT NULL AND
NOT EXISTS
(
SELECT
pp.id
FROM
product pp
WHERE
pp.box_id = p.box_id AND
pp.last_activity > p.last_activity
)
)
)
答案 1 :(得分:0)
你可以使用union来获取box_is为null的所有行,而不是获取具有最大id和日期的行,其中box_id不为null:
SELECT * FROM
(
SELECT id,owner_id,last_activity,box_id FROM product WHERE owner_id = 2 AND box_id IS NULL
UNION
SELECT MAX(id),owner_id,MAX(last_activity),box_id FROM product WHERE owner_id = 2 AND box_id IS NOT NULL GROUP BY owner_id, box_id
) T1
ORDER BY
id
答案 2 :(得分:0)
ROW_NUMBER
分析函数可能有助于此类查询:
SELECT "owner_id", "id", "box_id", "last_activity" FROM
(
SELECT "owner_id", "id", "box_id", "last_activity",
ROW_NUMBER()
OVER (PARTITION BY "box_id" ORDER BY "last_activity" DESC NULLS LAST) rn
-- ^^^^^^^^^^^^^^^
-- descending order, reject nulls after not null values
-- (this is the default, but making it
-- explicit here for self-documentation
-- purpose)
FROM T
WHERE "owner_id" = 2
) V
WHERE rn = 1 or "box_id" IS NULL
ORDER BY "id" -- <-- probably not necessary, but matches your example
请参阅http://sqlfiddle.com/#!4/db775/8
可以将null作为值。如果框内的所有产品都有空值,则应返回MIN(id)
即使可能不依靠id
来订购内容的好主意,您认为需要这样做,您必须将ORDER BY
条款更改为:
... ORDER BY "last_activity" DESC NULLS LAST, "id" DESC
-- ^^^^^^^^^^^