我有一个存储过程,其中有两个参数user-defined table type
:
ALTER PROCEDURE MyProcedure
@ReceivedBooks tp_Books READONLY,
@ReceivedIdAuthors tp_Authors READONLY,
AS
用户定义的表类型的结构如下所示:
CREATE TYPE [dbo].[tp_Books] AS TABLE(
[BookName] [VARCHAR](50) NULL
)
CREATE TYPE [dbo].[tp_Authors] AS TABLE(
[AuthorIds] [VARCHAR](50) NULL
)
此外,我有两个表Books
和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 |
---------------------------------------------
例如,我在存储过程中收到以下值的@ReceivedBooks
和@idAuthors
:
'Hamlet', 'Romeo and Juliet' --@ReceivedBooks
1, 2, 3, 5 --@ReceivedIdAuthors
然后我知道1
是我想要找到的Id_Author
。由于以下EXCEPT
语句不返回IdAuthor = 1
的任何行(William Shakespeare(ID=1
),因此是Hamlet
和Romeo and Juliet
的作者。而1
是idAuthor
Author
我希望找到的原因EXCEPT
语句不返回任何行:
SELECT * FROM @ReceivedBooks
EXCEPT
SELECT Name FROM #Books WHERE IdAuthor IN (1)
让我举个例子,其中EXCEPT
语句返回行。因此,Id_Author
不是我想要的。
SELECT * FROM @ReceivedBooks
EXCEPT
SELECT Name FROM #Books WHERE IdAuthor IN (2) -- 3, 5
所以我的目标是在id_author
中找到必要的@ReceivedIdAuthors
。
我怎样才能做到这一点?
答案 0 :(得分:2)
根据其他澄清评论,您似乎真正需要的是:
@ReceivedBooks
参数中的所有图书是否属于同一作者,@ReceivedIdAuthors
参数中。此处使用的技术称为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;
答案 1 :(得分:1)
基本上,你想要返回@List中不包含此人的第一个元组(人,部门)?
@List有多大?如果相当小,你可以使用:
SELECT dep.Name,
pr.ID
FROM dbo.Person AS pr
INNER JOIN dbo.Department AS dep ON dep.ID = pr.id_Person
WHERE id_Person = @personId
AND id_Person NOT IN @List
LIMIT 1;
此外,我认为您不需要迭代查询,至少不会给出我在问题描述中看到的数据。