我有几个表最简单的表格为1:N;例如:
CREATE TABLE X (id INTEGER, foo VARCHAR(16));
CREATE TABLE Y (id INTEGER, x_id INTEGER, bar VARCHAR(16));
和里面的一些数据,如:
INSERT INTO X VALUES (1, 'a'), (2, 'b'), (3, 'c');
INSERT INTO Y VALUES
(1, 1, 'blue'), (2, 1, 'green'), (3, 1, 'red'),
(4, 2, 'big'), (5, 2, 'small'),
(6, 3, 'car'), (7, 3, 'bike'), (8, 3, 'skate');
我想做什么:从两个表中选择实体,限制x.id
。例如,我需要选择2个实体,然后这将无法正常工作:
SELECT x.id, x.foo, y.id, y.bar
FROM x INNER JOIN y ON x.id = y.x_id
LIMIT 2
因为if会对最终生成的行集应用限制,而不是基于x.id
。结果应该是:
x.id x.foo y.id y.bar
1 'a' 1 'blue'
1 'a' 2 'green'
1 'a' 3 'red'
2 'b' 4 'big'
2 'b' 5 'small'
我的想法是编写一些块分子,它将添加" block"数字到结果行集,然后代替LIMIT
使用WHERE
,所以:
SELECT block_number, x.id, x.foo, y.id, y.bar
FROM x INNER JOIN y ON x.id = y.x_id
WHERE block_number <= 2
但到目前为止,我没有找到任何获得该区号的好方法。 &#34;良好的&#34;的意思是:
我尝试过这样的事情:
SELECT row_number() OVER (PARTITION BY x.id), x.id, x.foo, y.id, y.bar
FROM x INNER JOIN y ON x.id = y.x_id
WHERE block_number <= 2
但是,遗憾的是,这会在块中提供行号,而不是每块,因此不能用于我的问题。
此外,选择x
记录并限制它&#34;事先&#34;在这样的子查询中:
SELECT x.id, x.foo, y.id, y.bar
FROM
(SELECT x.id LIMIT 2) AS x
INNER JOIN y ON x.id = y.x_id
不是一种选择。这是因为:
ORDER BY
子句,因为我无法为仅针对表ORDER BY
的子查询编写正确的x
所以,重要添加:解决方案应该尊重原始查询顺序。最简单的说明方式是:
SELECT block_number, x.id, x.foo, y.id, y.bar
FROM x INNER JOIN y ON x.id = y.x_id
WHERE block_number <= 2
ORDER BY x.id DESC
应该产生:
block_number x.id x.foo y.id y.bar
1 3 'c' 6 'car'
1 3 'c' 7 'bike'
1 3 'c' 8 'skate'
2 2 'b' 4 'big'
2 2 'b' 5 'small'
即。应该正确计算块以保持原始订单。而且,我无法预测初始订单,因为它是动态指定的。
P.S。
抱歉,因为没有提供sql小提琴。该资源不适合我,而且已经很长时间了。
另外,我的Postgres版本是:9.4
,所以任何&#34; new&#34;可以实现我的目标的功能 - 可以应用。
答案 0 :(得分:3)
您可以使用窗口函数dense_rank()
。
无法在WHERE子句中调用窗口函数,因此必须将其放在子查询中:
<div class="collapse navbar-collapse" id="navbar-brand-centered">