我是sql的初学者。我对选择特定的行值有疑问。
这是数据
| KEY | LOCATION | IDX |
| ---- | -------- | ---- |
| 01 | 1-01 | 0 |
| 01 | 1-02 | 1 |
| 01 | 1-03 | 2 |
| 02 | null | 0 |
| 02 | 2-02 | 1 |
| 02 | 2-03 | 2 |
| 03 | null | 0 |
| 03 | null | 1 |
| 03 | null | 2 |
我期望什么?
| KEY | LOCATION | IDX |
| ---- | -------- | ---- |
| 01 | 1-01 | 0 |
| 02 | 2-02 | 1 |
| 03 | null | 1 |
对于同一个KEY,我想获取IDX = 0且LOCATION不为null的值,如果不是,则返回IDX = 1的值;
有没有办法做到这一点?我正在使用sqlite3。
感谢帮助!
答案 0 :(得分:1)
这是一个棘手的问题,因为您正在查看不同行之间的关系。该解决方案类似于Barbaros的解决方案。但是,SQLite支持CTE,因此我更喜欢将其表示为:
with l0 as (
select t.*
from t
where t.location is not null and t.idx = 0
)
select l0.*
from l0
union all
select t.*
from t
where idx = 1 and
not exists (select 1 from l0 where l0.key = l1.key);
也就是说,拿走l0
中符合您条件的所有物品。然后使用idx = 0
获取不符合该条件的其他键。
答案 1 :(得分:0)
我会这样:
SELECT
z.key,
CASE WHEN z.location is not null
THEN z.location
ELSE o.location
END as location,
CASE WHEN z.location is not null
THEN z.idx
ELSE o.idx
END as idx
FROM
(SELECT * FROM t WHERE idx=0) z
INNER JOIN
(SELECT * FROM t WHERE idx=1) o
ON z.key = o.key
答案 2 :(得分:0)
您可以将union all
与not in
一起使用
with tab( KEY, LOCATION, IDX ) as
(
select '01','1-01', 0 union all
select '01','1-02', 1 union all
select '01','1-03', 2 union all
select '02', null , 0 union all
select '02','2-02', 1 union all
select '02','2-03', 2 union all
select '03', null , 0 union all
select '03', null , 1 union all
select '03', null , 2
)
select * from tab where location is not null and idx =0
union all
select * from tab t where idx =1
and key not in
( select key
from tab
where location is not null and idx =0
)
key location idx
---- -------- ---
01 1-01 0
02 2-02 1
03 NULL 1
答案 3 :(得分:0)
首先,仅获取那些可能有用的行:
SELECT *
FROM t
WHERE (idx = 0 AND location IS NOT NULL)
OR idx = 1;
key location idx ---------- ---------- ---------- 01 1-01 0 01 1-02 1 02 2-02 1 03 1
然后使用分组每个键仅返回一行。如果有两个表行,则要使用较小的idx
,因此请使用MIN()进行选择:
SELECT key, location, MIN(idx) AS idx
FROM t
WHERE (idx = 0 AND location IS NOT NULL)
OR idx = 1
GROUP BY key;
key location idx ---------- ---------- ---------- 01 1-01 0 02 2-02 1 03 1