[英]SQL: Select all rows that meet a condition if that condition is met, but only a certain nuber rows if it isn't
[英]Get only first N rows met the condition but keep rows where the condition isn't met
ID | 類型 |
---|---|
1 | 身體 |
2 | 身體1 |
3 | 身體 |
4 | 身體1 |
5 | 身體1 |
6 | 身體1 |
7 | 身體 |
8 | 身體1 |
9 | 身體1 |
10 | 身體 |
是否可以 select 前 3 行type
為body
但保留其他type
不等於body
的行? 預期結果是 id 從 1 到 7 的行。
你似乎想要一切到第三個body
。 一種方法是:
select t.*
from t
where t.id <= (select t2.id
from t t2
where t2.type = 'body'
order by t2.id
limit 1 offset 2
);
注意:此特定公式假定至少有三個'body'
行。 可以對其進行調整,但這與您的示例數據一致。
這是你想要的?
SELECT * FROM <table> WHERE type = 'body' ORDER BY id LIMIT 3
ORDER BY 將確保您 select 由 id 列排序的頂部行
LIMIT 3 將只選擇前 3 個結果
另一種解決方案是使用排名
復制你的桌子
create table test_body (id integer, str_type varchar);
insert into test_body values(1, 'body');
insert into test_body values(2, 'body1');
insert into test_body values(3, 'body');
insert into test_body values(4, 'body1');
insert into test_body values(5, 'body1');
insert into test_body values(6, 'body1');
insert into test_body values(7, 'body');
insert into test_body values(8, 'body1');
insert into test_body values(9, 'body1');
insert into test_body values(10, 'body');
以下查詢計算條件的排名,然后使用它來過濾數據
with ranking_sel as(
select *,
case when str_type = 'body' then 1 else 0 end condition,
rank() over (partition by case when str_type = 'body' then 1 else 0 end order by id) rnk from test_body
)
select * from ranking_sel where rnk <= 3 or condition = 0 order by id;
您需要使用 window function DENSE_RANK()
:
SELECT
*
FROM
(
SELECT
DENSE_RANK() OVER (PARTITION BY t1.type ORDER BY t1.id) rnk,
t1.*
FROM table t1
) t2
WHERE
(t2.type = 'body' and rnk <= 3) or (t2.type != 'body')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.