通过将其连接到另一个表来使用一个表中的每一行

时间:2009-09-18 20:53:00

标签: sql sql-server tsql sql-server-2008

我想要一个最简单的查询,将两个表连接在一起,除了每行之外没有其他表达关系,我将称之为“池”表将匹配到我的另一个表中的精确1行。我不关心哪一行,我只想让主表中的每一行从“pool”表中获取一行,并且知道池中的每一行只能使用一次。

我在想像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(IDENTITY)。现在,我想在对象特定表中使用类似的INSERT,但是我需要将@idsTable中的ID与我的select查询中的1行匹配(因此我的插入查询)。类似的东西:

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

3 个答案:

答案 0 :(得分:2)

你为什么放弃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

答案 1 :(得分:1)

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

  • 使用DEFAULT值CONSTRAINT(NEWID())向您的UNIQUEIDENTIFIER表添加一个简单的RecordsToWrite列UID,以便自动生成它。
  • 将您的@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上工作正常,这意味着我也可以使用OUTPUT和INSERT。你也可以尝试:

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

答案 2 :(得分:0)

也许是我的误解,但你不能这样做:

SELECT * FROM @ idsTable,RecordsToWrite

或做交叉加入