【问题标题】:Get ID by query result通过查询结果获取 ID
【发布时间】:2018-07-29 14:41:51
【问题描述】:

我有一个存储过程,它有两个参数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
)

另外,我还有两张表BooksAuthors

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) 是HamletRomeo and Juliet 的作者)。而1 是我想要找到的AuthoridAuthor,因为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

所以我的目标是在@ReceivedIdAuthors中找到必要的id_author

我怎样才能做到这一点?

【问题讨论】:

  • 样本数据和期望的结果确实有助于解释您想要做什么。 while 循环似乎不太必要。
  • 最好用简单的英语解释您的业务需求(而不是您的解决方案)。
  • @GordonLinoff,请看我更新的问题。
  • @RogerWolf 请看我更新的问题。
  • 澄清一下,查询的 except 部分实际上返回 2 个结果('Hamlet' 和 'Romeo and Juliet'),但整个查询(应用于您的第一个 select 语句的 except 部分)会返回空值。我的一个问题是,如果您在“已接收书籍”中的书籍来自两位不同的作者,那么查询将永远不会返回 null,因为您当时只排除了一位作者的书籍。如果您的“已接收图书”列表中的所有图书均由同一作者撰写,您是否只想获取作者姓名?

标签: sql sql-server tsql except


【解决方案1】:

根据额外的澄清 cmets,您似乎真正需要的是:

  • 查找@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;

【讨论】:

    【解决方案2】:

    基本上,您想要返回 (person, department) 的第一个元组,其中人员不包含在@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;
    

    另外,我认为您不需要遍历查询,至少没有给出我在您的问题描述中可以看到的数据。

    【讨论】:

    • 不,我想比较两个查询的结果,其中一个是在迭代中执行的。当EXPECT 没有返回任何行时,我想获得第一个ID
    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    相关资源
    最近更新 更多