Найти общие значения между SQL таблицей и списком в SQL Запрос, подобный этому - PullRequest
3 голосов
/ 16 апреля 2020

Это мой пример набора данных ...

CREATE TABLE blockhashtable (id int PRIMARY KEY AUTO_INCREMENT,pos int,filehash varchar(35), blockhash varchar(130) );

insert into blockhashtable 
(pos,filehash,blockhash) values 
(1, "random_md51", "randstr1"),
(2, "random_md51", "randstr2"),
(3, "random_md51", "randstr3"),
(1, "random_md52", "randstr2"),
(2, "random_md52", "randstr2"),
(3, "random_md52", "randstr2"),
(4, "random_md52", "randstr1"),
(5, "random_md52", "randstr7"),
(1, "random_md53", "randstr2"),
(2, "random_md53", "randstr1"),
(3, "random_md53", "randstr2"),
(4, "random_md53", "randstr1"),
(1, "random_md54", "randstr1"),
(2, "random_md54", "randstr55");

Ток SQL Запрос (необходимо исправить):

SELECT filehash
     , GROUP_CONCAT(pos ORDER BY pos) pos
     , (avg(blockhash IN('randstr1','randstr2','randstr3','randstr2','randstr2'))) as ratio
  FROM blockhashtable
 GROUP
    BY filehash

Токовый выход (Необходимо исправить)

filehash    pos        ratio
random_md51 1,2,3      1
random_md52 1,2,3,4,5  0.8
random_md53 1,2,3,4    1
random_md54 1,2        0.5

SQL Fiddle: http://sqlfiddle.com/#! 9 / 6b5220 / 10

Ожидаемый результат:

filehash    pos        ratio
random_md51 1,2,3      1
random_md52 1,2,3,4    0.8
random_md53 1,2,3      0.75
random_md54 1          0.5

Я в основном пытаясь найти «похожую блокху sh» между списком запросов и таблицей sql.

О столбцах соотношения:

Если randomstr1 появляется только один раз в запросе SQL, то я хочу получить максимум 1 совпадение для randomstr1 в SQL дБ.

В третьей строке вывода. ratio равно 0,75, потому что randomstr1 появляются только один раз в запросе, даже если они дважды появляются в таблице MySQL. Итак, в третьем ряду мы нашли совпадение 3/4. randomstr2 сопоставляется оба раза в третьей строке, поскольку оно появляется 2 или более раз в запросе SQL.

О pos. Я просто хочу знать pos значение matched blocks.

1 Ответ

1 голос
/ 17 апреля 2020

С помощью оконной функции ROW_NUMBER() вы можете проверить, существует ли «randomstr1» более чем или «randomstr2» существует более 3 раз, поэтому вы можете игнорировать их:

with 
  row_numbers as (
    select *, 
      row_number() over (partition by filehash, blockhash order by pos) rn
    from blockhashtable 
  ),
  cte as (
    select *, 
    (blockhash = 'randstr1' and rn = 1)
    or 
    (blockhash = 'randstr2' and rn <= 3)
    or 
    (blockhash = 'randstr3') valid
    from row_numbers
  )
select filehash,
  group_concat(case when valid then pos end order by pos) pos,
  avg(valid) as ratio
from cte
group by filehash

См. Демонстрационную версию . Результаты:

> filehash    | pos     |  ratio
> :---------- | :------ | -----:
> random_md51 | 1,2,3   | 1.00
> random_md52 | 1,2,3,4 | 0.80
> random_md53 | 1,2,3   | 0.75
> random_md54 | 1       | 0.50
...