通过比较查询结果查找ID

时间:2018-07-08 12:10:50

标签: sql sql-server tsql

我有一个表变量Names,其中包含以下数据:

SELECT * FROM Names

及其结果:

Name
-----
Jon
Adam 
Ben
Joseph

此外,还有一个函数fn_GetNamesById(@Id)通过Name(1)获得id

SELECT * FROM fn_GetColumns(1) 

及其结果将是:

Name
-----
Jon
Adam 
Ben
Joseph

另一个id(2)将返回另一个结果

SELECT * FROM fn_GetColumns(2) 

及其结果将是:

Name
-----
Adam 
Jon
Joseph
Ben

另一个id(3)将返回另一个结果:

SELECT * FROM fn_GetColumns(3) 

及其结果将是:

Name
-----
Marc
William 
Gordon
Wiktor
Felix

我想通过比较表变量UDF/Stored procedure的结果和函数Find_ID(@IDs, @Names)的结果在名为Names的{​​{1}}中找到id。

fn_GetColumns(id)的参数为:

Stored Procedure/UDF

为此,我编写了一个@IDs TABLE(ID uniqueidentifier) -- possible IDs (1,2,3, ...1000) @Names TABLE(ID uniqueidentifier) -- desired names ,其中包含一个循环stored procedure Find_ID 以遍历ID 。当前的 id 将被放在函数WHILE中,然后将fn_GetColumns(id)的结果与结果表变量fn_GetColumns(id)进行比较。

但是,如果查询结果相同,我不知道如何比较两个查询结果并获得最新的@Names

id

如果查询结果相同,是否可以找到功能-- My stored procedure CREATE PROCEDURE [Find_ID] ( @IDs [UWQ].[TY_MyType] READONLY, @Names [UWQ].[TY_MyNames] READONLY DECLARE @IDs TABLE(ID uniqueidentifier) DECLARE @Names TABLE(ID uniqueidentifier) DECLARE @Processed INT DECLARE @COUNTER INT = 0; DECLARE @MAX INT = (SELECT COUNT(*) FROM @IDs) DECLARE @VALUE VARCHAR(50); --loop: WHILE @COUNTER < @MAX BEGIN --we are iterating through id = 1, 2, 3 SET @VALUE = (SELECT ID FROM (SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) [index] , ID from @IDs) R ORDER BY R.[index] OFFSET @COUNTER ROWS FETCH NEXT 1 ROWS ONLY); // pseudo code: if SELECT * FROM fn_GetColumns(1) is equal to SELECT * // FROM Names THEN return @VALUE // pseudo code: else iterate to find id // pseudo code: if there is no names then return NULL SET @COUNTER = @COUNTER + 1 END 的{​​{1}}?

例如:

id

输出:1 -与UDF fn_GetColumns(id)返回相同的查询结果
                 像DECLARE @Names table ( Names VARCHAR(50) ) insert into @Names VALUES (Jon), (Adam) , (Ben), (Joseph) DECLARE @Ids table ( ID int ) insert into @Ids VALUES (1),(2) , (3), (4) EXEC Find_ID(@IDs, @Names)

2 个答案:

答案 0 :(得分:1)

假设名称不同,可以执行以下操作:

SELECT (CASE WHEN COUNT(*) = nn.cnt THEN 1 ELSE 0 END) as all_same
FROM Names n JOIN
     fn_GetColumns(@id) gc(name)
     ON n.name = gc.name CROSS JOIN
     (SELECT COUNT(*) as cnt FROM names) nn;

这将计算匹配数并将其与名称总数进行比较。

答案 1 :(得分:0)

我意识到我可以只计算EXCEPT运算符的查询结果。如果唯一行数为0,则意味着找到了必要的ID

 SELECT 
     @DesiredID = count(1) 
 FROM 
 (
     SELECT * FROM (SELECT * FROM @Names) InputNames
     EXCEPT
     SELECT * FROM (SELECT TOP 1000 Name 
     FROM fn_GetColumns(@VALUE) ORDER BY ColumnOrder) DesiredNames
 ) rn

 IF @DesiredID = 0
 BEGIN
     PRINT @DesiredID
     PRINT @VALUE
     BREAK
 END

整个代码如下:

DECLARE @IDs TABLE(ID uniqueidentifier)
DECLARE @Processed INT
INSERT INTO @IDs
SELECT 
f.ID 
FROM Fields f
GROUP BY f.ID

DECLARE @Names TABLE
(
    Name varchar(50)
)

INSERT INTO @Names
VALUES
('Jon'), ('Adam'), ('Ben'), ('Joseph')



 DECLARE @COUNTER INT = 0;
 DECLARE @MAX INT = (SELECT COUNT(*) FROM @IDs)
 DECLARE @VALUE VARCHAR(50);
 DECLARE @DesiredID VARCHAR(50);

 WHILE @COUNTER < @MAX
 BEGIN

     SET @VALUE = (SELECT ID FROM
         (SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) [index] , ID from @IDs) R 
          ORDER BY R.[index] OFFSET @COUNTER 
          ROWS FETCH NEXT 1 ROWS ONLY);

          --PRINT @VALUE
         SELECT 
             @DesiredID = count(1) 
         FROM 
         (
             SELECT * FROM (SELECT * FROM @Names) InputNames
             EXCEPT
             SELECT * FROM (SELECT TOP 1000 Name 
             FROM fn_GetColumns(@VALUE) ORDER BY ColumnOrder) DesiredNames
         ) rn

         IF @DesiredID = 0
         BEGIN
             PRINT @DesiredID
             PRINT @VALUE
         BREAK
     END

     SET @COUNTER = @COUNTER + 1

END