I have a stored procedure which has two parameters of user-defined table type
:
ALTER PROCEDURE MyProcedure
@ReceivedBooks tp_Books READONLY,
@ReceivedIdAuthors tp_Authors READONLY,
AS
The structure of user-defined table type looks like this:
CREATE TYPE [dbo].[tp_Books] AS TABLE(
[BookName] [VARCHAR](50) NULL
)
CREATE TYPE [dbo].[tp_Authors] AS TABLE(
[AuthorIds] [VARCHAR](50) NULL
)
In addition, I have two tables Books
and Authors
:
Books
:
----------------------------------------------------------------
| ID | Name | Id_Author |
----------------------------------------------------------------
| 1 | Hamlet | 1 |
| 2 | Spartaco | 2 |
| 10 | Romeo and Juliet | 1 |
| 11 | Great Expectations | 3 |
| 12 | Pride and Prejudice | 5 |
| 13 | A Tale of Two cities | 3 |
----------------------------------------------------------------
Authors
:
---------------------------------------------
| ID | Name |
---------------------------------------------
| 1 | William Shakespeare |
| 2 | Raffaello Giovagnoli |
| 3 | Charles Dickens |
| 5 | Jane Austin |
---------------------------------------------
For example, I receive @ReceivedBooks
and @idAuthors
with following values at my stored procedure:
'Hamlet', 'Romeo and Juliet' --@ReceivedBooks
1, 2, 3, 5 --@ReceivedIdAuthors
then I can know that 1
is the Id_Author
which I want to find. As the following EXCEPT
statement returns no rows for IdAuthor = 1
(William Shakespeare(ID=1
) is an author of Hamlet
and Romeo and Juliet
). And 1
is the idAuthor
of Author
that I want to found cause EXCEPT
statement returns no rows:
SELECT * FROM @ReceivedBooks
EXCEPT
SELECT Name FROM #Books WHERE IdAuthor IN (1)
Let me show an example, where EXCEPT
statement returns rows. Consequently, this Id_Author
is not what I want.
SELECT * FROM @ReceivedBooks
EXCEPT
SELECT Name FROM #Books WHERE IdAuthor IN (2) -- 3, 5
So my goal is to find necessary id_author
in @ReceivedIdAuthors
.
How can I achieve this?
Based on additional clarification comments, it seems all you really need is:
@ReceivedBooks
parameter belong to the same author, and@ReceivedIdAuthors
parameter.The technique to use here is called relational division:
select b.Id_Author
from @ReceivedBooks rb
inner join dbo.Books b on b.Name = rb.BookName
where exists (
select 0 from @ReceivedIdAuthors ra
where ra.AuthorId = b.Id_Author
)
group by b.Id_Author
having count(distinct b.Id_Author) = 1;