Выберите из таблицы, только если все значения динамических параметров совпадают - PullRequest
0 голосов
/ 10 мая 2018

У меня есть следующая animal таблица:

id      | action
------------------
duck    | cuack
duck    | fly
duck    | swim    
pelican | fly
pelican | swim

Я хочу создать хранимую процедуру и передать группу значений в один параметр:

EXEC GuessAnimalName 'cuack,fly,swim'

Result:
duck

Так что, если он вздрагивает, летает и плавает, значит, это утка. Но также:

EXEC GuessAnimalName 'fly,swim'

Result:
pelican

---

EXEC GuessAnimalName 'fly'

Result:
No results

Номер параметра является динамическим.

Чтобы угадать имя животного, все указанные действия должны совпадать или находиться в таблице animal.

Это то, что я имею до сих пор:

DECLARE @animal AS TABLE
(
    [id] nvarchar(8),
    [action] nvarchar(16)
)

INSERT INTO @animal VALUES('duck','cuack')
INSERT INTO @animal VALUES('duck','fly')
INSERT INTO @animal VALUES('duck','swim')
INSERT INTO @animal VALUES('pelican','fly')
INSERT INTO @animal VALUES('pelican','swim')

-- Parameter simulation
DECLARE @params AS TABLE
(
    [action] nvarchar(16)
)

INSERT INTO @params VALUES('cuack')
INSERT INTO @params VALUES('fly')
INSERT INTO @params VALUES('swim')

SELECT
    a.[id]
FROM
    @animal a
INNER JOIN
    @params p
ON
    a.[action] = p.[action]
GROUP BY
    a.[id]
HAVING COUNT(a.[action]) IN (SELECT COUNT([action]) FROM @animal GROUP BY [id])

Что дает результат:

Result:
--------
duck
--------
pelican

Возвращается только duck.

1 Ответ

0 голосов
/ 10 мая 2018

преобразовать это в сохраненный процесс, используя RANK

declare @lookfor varchar(100) = 'swim,fly'

select id from 
(select 
id, rank() over (order by cnt desc)  rank_   -- get rank based on the number of match where should be the same number of rows
from
(
SELECT
    a.id, count(1) cnt   -- identify how many matches
FROM
    @animal a
INNER JOIN
    @params p
ON
    a.[action] = p.[action]
where charindex(p.action,@lookfor) > 0
group by a.id
having count(1) = (select count(1) from @animal x where a.id = x.id))  -- only get the animal with the same number of matches and rows
y)
z where rank_  = 1   -- display only with the most matches which should be the same number of rows matched

вам не нужно @params здесь

select id from 
(select 
id, rank() over (order by cnt desc)  rank_
from
(
SELECT
    a.id, count(1) cnt 
FROM
    @animal a
where charindex(a.action,@lookfor) > 0
group by a.id
having count(1) = (select count(1) from @animal x where a.id = x.id))
y)
z where rank_  = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...