Как выбрать конкретную строку, если база данных sqlite содержит несколько строк с одинаковыми именами / функциями - PullRequest
0 голосов
/ 06 января 2019

Я новичок в 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 не равно нулю, и, если нет, вернуть значение, для которого IDX = 1;

Есть ли способ сделать это? Я использую sqlite3.

Ценю помощь!

Ответы [ 4 ]

0 голосов
/ 06 января 2019

Во-первых, получите только те строки, которые могут быть полезны:

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         
0 голосов
/ 06 января 2019

Вы можете использовать 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

Rextester Demo

0 голосов
/ 06 января 2019

Это сложная проблема, потому что вы смотрите на отношения между различными строками. Это решение похоже на решение Барбароса. Однако 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, которые соответствуют вашим условиям. Затем возьмите idx = 1 для дополнительных ключей, которые не соответствуют этому условию.

0 голосов
/ 06 января 2019

Я бы сделал это так:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...