2009-09-18 22 views
0

我想要一个查询,在其最简单的情况下将连接2个表格,除了每行之外没有其他表达关系,我将称之为“池”表格与我另一张桌子中的恰好一排相匹配。我不关心哪一行,我只是希望主表中的每一行都从“池”表中获取一行,并知道池中的每一行只能使用一次。通过将其连接到另一个表中使用每一行

我想这样ROW_NUMBER()OVER()可以用来匹配上会被罚款的任意行号,但我认为至少需要2级内部行集的提供者;我认为会有些简单的事情。

为了更简洁地把这个问题了一下,你有ID的表,你想它加入到记录表来分配的ID。你只能使用每个id一次。您可以使用哪种查询结构或连接来返回分配给ID的所有记录的行集。记录得到什么ID并不重要,只是每个ID只能使用一次。

背景

对于那些你感兴趣的背景,我有什么是它是由一个头表头行的一个逻辑实体,它是通用的,以大量的对象这给我们的ID,然后是实体特定表中的记录。我使用类似下面的查询预生成一串的ID在头表:

declare @idsTable TABLE(ID INT); 

INSERT INTO Header (HeaderType) 
OUTPUT INSERTED.id INTO @idsTable 
SELECT 4 as HeaderType 
    FROM Company c WHERE c.CompanyType = 12; 

在这一点上我有一大堆的标题行和已分配给该行的ID(身份)的。现在,我想用类似的插入对象特定表,但我需要从@idsTable的ID在我的选择查询(因此我的插入查询)匹配到只有1行。喜欢的东西:

INSERT INTO Specific (HeaderiD, Value1, ...) 
SELECT * 
    FROM @idsTable 
    JOIN RecordsToWrite r2r ON ??? 

回答

1

你为什么放弃ROW_NUMBER? Adventure Works示例

SELECT 
    * 
FROM 
(
    SELECT 
     TOP 10 ROW_NUMBER() OVER(ORDER BY EmployeeId) AS join_id,* 
    FROM 
     HumanResources.Employee 
) t1 
INNER JOIN 
(
    SELECT 
     TOP 10 ROW_NUMBER() OVER(ORDER BY DepartmentId) AS join_id,* 
    FROM 
     HumanResources.Department 
) t2 ON t1.join_id = t2.join_id 
+0

我没有放弃,我只是认为它不是特别易读,并且会有些简单的事情。顺便说一句,这正是row_number解决方案的意思。 – 2009-09-18 21:45:59

0

也许我误解,但不能你只是做:

SELECT * FROM @ idsTable,RecordsToWrite

或做一个交叉联接

+0

这将是两者之间的每种组合;您只能使用idstable ONCE中的一行。 – 2009-09-18 21:00:13

1

如果我正确理解您的数据,然后在RecordsToWrite表中的行数和那来自查询... FROM公司新的行数......应该是相同的。在这种情况下:

  • 添加一个简单的UNIQUEIDENTIFIER列UID您RecordsToWrite表默认值约束(NEWID()),所以它是自动生成的。
  • 您@idsTable表,并语句更改这个

-

declare @idsTable TABLE(ID INT, UID UNIQUEIDENTIFIER); 
INSERT INTO Header (HeaderType) 
OUTPUT INSERTED.id, r.UID INTO @idsTable 
SELECT 4 AS HeaderType, r.UID 
FROM RecordsToWrite r --// maybe other filters to get only number or records as in: 
--//FROM Company c WHERE c.CompanyType = 12; 

然后在你的第二个查询这个UID列加入。

编辑:新 以下代码在我的sql-2008上正常工作,这意味着我可以在INSERT中使用OUTPUT。所以你能,只是尝试:

CREATE TABLE TestOutput (ID INT IDENTITY, TAG VARCHAR(10)); 

DECLARE @idsTable TABLE(ID INT, UID UNIQUEIDENTIFIER); 

INSERT INTO TestOutput (TAG) 
OUTPUT INSERTED.id, NEWID() INTO @idsTable 
SELECT tag 
FROM ( SELECT 'test-1' as tag 
UNION ALL SELECT 'test-2' 
) x 

SELECT * FROM @idsTable 
SELECT * FROM TestOutput 

DROP TABLE TestOutput; 

,我得到如下结果:

ID   UID 
----------- ------------------------------------ 
1   422FF4F0-9CFB-4F67-94C8-2D3B225E39B0 
2   0BD2B2D2-1319-4981-9E26-C09FE844359C 

ID   TAG 
----------- ---------- 
1   test-1 
2   test-2 
+0

我使用类似的方法在关系数据库中存储对象,其中基类存储在一个表中,特定于子表的特定子类存储在这些表中。但区别在于,我实际上保留了父级别的UID列,以便每个对象都具有全局UID。尽管如此,我并没有将它保留在子表上,因为所有的FK和表链接都是在INT列上完成的,而不是在UID上完成的。拥有UID给了我更多的灵活性,因为我也可以从客户端代码中指定它,并且仍然能够链接到进一步查询的对象。 – van 2009-09-18 21:53:08

+0

由于您仅插入(HeaderType)列,并且您从选择查询中选择了2列,因此此查询不能按书面形式工作。不太流行,我从来没有能够让OUTPUT语句接受任何不是来自INSERTED表的东西。当我尝试时,我得到一个“多部分标识符”r.UID“无法绑定”。错误。在这种情况下,修改HEADER表以在那里获取Guid是不可接受的。 – 2009-09-21 18:04:29

+0

为了更清楚一点,这是我认为可能存在但不能工作的简单方法。如果这可行,我很乐意。 – 2009-09-21 18:05:35

相关问题