SQL:从一个表中加入两个具有不同行的表

时间:2013-07-10 10:52:01

标签: sql sql-server-2008 tsql join

这可能是一个非常简单的问题,但自从昨晚以来我似乎无法理解这个问题。

我有3张桌子

VirtualLicense
VirtualLicenseId    ProductName
-----------------------------------
1           Transaction
2           Query
3           Transaction


Product
ProductId   Name
---------------------------
1           Transaction
2           Query


License
LicenseId   ExpiryDate  ProductId
-----------------------------------------
1           14/07/2013  1
2           13/07/2013  1
3           13/07/2013  2
4           14/07/2013  2

使用Product表格使用ProductName和ProductId映射连接VirtualLicense和许可证。

我想获得VirtualLicenseId和LicenseId的组合,我基本上可以将VirtualLicenseId分配给LicenseId。将licenseid分配给VirtualLicenseId后,它不应该可用于以下VirtualLicenseIds。另外,我希望首先分配expirydate更近(更小)的licenseid。

因此,我的示例数据集的结果应为

VirtualLicenseId    LicenseId
---------------------------------
1                   2
2                   3
3                   1

我不想为此循环任何表。 我希望我的描述和数据能清楚我的问题。

1 个答案:

答案 0 :(得分:2)

您可以这样做:

  • 在第一次CTE中 - 为产品组中的VirtualLicenses分配排名。
  • 在第二次CTE中 - 为产品组内的许可证分配排名(按日期排序)
  • 最后,只需加入productID和排名上的两个子查询。

WITH CTE_VL AS 
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ProductId ORDER BY vl.VirtualLicenseId ASC) RN
    FROM dbo.VirtualLicense vl
    LEFT JOIN dbo.Product p ON vl.ProductName = p.Name
)
,CTE_License AS
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ProductId ORDER BY ExpiryDate ASC) RN
    FROM dbo.License 
)
SELECT VirtualLicenseId, LicenseId 
FROM CTE_VL vl
LEFT JOIN CTE_License l ON vl.ProductId = l.ProductID AND vl.RN = l.RN

<强> SQLFiddle DEMO