Найти строки с «не похожими друг на друга» столбцом 1, когда столбец 2 совпадает - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть одна таблица с 2 столбцами в базе данных fls2, которая является Sqlite;

name        |    sha256
------------|------------------
ab/ac/ad    |    12345
ab/ad/af    |    12345
zx/ad/af    |    12345

Я хотел бы найти имена, в которых 'name like' ab% 'и' name not like 'ab%' оба верны для определенного ша256. Таким образом, в приведенном выше случае 3 строки совместно используют sha256 из «12345», и я хотел бы рассмотреть этот набор данных. В этом наборе данных, если оба 'name like' ab% 'и' name not like 'ab%' истинны (очевидно, для 2 или более разных строк), я бы хотел, чтобы все строки возвращались.

Я занимаюсь поиском случаев, когда идентичный файл (идентифицируемый его sha256) присутствует в 2 разных каталогах верхнего уровня.

Я знаю, как сделать это в perl после извлечения данных, но в идеале, если бы я мог сделать это в БД, это было бы намного лучше. Я пытался

select name 
from 
    fls2 
where 
    sha256 = (select sha256 from fls2 where name like 'ab%') 
and 
    name not like 'ab%';

Но он не возвращает никаких строк (и я знаю, что есть хотя бы несколько, потому что я нашел их вручную).

Ответы [ 3 ]

1 голос
/ 23 февраля 2020

Использовать агрегацию и having:

select sha226, group_concat(name) as names
from t
group by sha226
having sum(case when name like 'ab%' then 1 else 0 end) > 0 and
       sum(case when name not like 'ab%' then 1 else 0 end) > 0;

. Все имена в списке помещаются в одну строку.

1 голос
/ 23 февраля 2020

Использование EXISTS:

select * from fls2 f
where
  exists (select 1 from fls2 where sha256 = f.sha256 and name like 'ab%')
  and
  exists (select 1 from fls2 where sha256 = f.sha256 and name not like 'ab%')

См. Демоверсию . Или с sum() оконной функцией:

select f.name, f.sha256
from (
  select *, 
    sum(name like 'ab%') over (partition by sha256) sum1,
    sum(name not like 'ab%') over (partition by sha256) sum2
  from fls2
) f
where f.sum1 > 0 and f.sum2 > 0

См. demo . Результаты:

| name     | sha256 |
| -------- | ------ |
| ab/ac/ad | 12345  |
| ab/ad/af | 12345  |
| zx/ad/af | 12345  |
0 голосов
/ 23 февраля 2020

В этом наборе данных, если оба 'name like' ab% 'и' name not like 'ab%' истинны (очевидно, для 2 или более разных строк), я бы хотел, чтобы все строки возвращались.

Вы можете использовать функции окна:

select name, sha256
from (
    select 
        f.*,
        max(case when name like 'ab%' then 1 end) over(partition by sha256) max_ab,
        max(case when name not like 'ab%' then 1 end) over(partition by sha256) max_not_ab
    from fls2 f
) t
where max_ab = 1 and max_not_ab = 1

В подзапросе окно max() s проверяет, существует ли запись с тем же sha256 и именем, которое начинается (соотв. не запускается) с 'ab%'. Затем внешний запрос фильтрует записи, которые удовлетворяют обоим условиям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...