2013-07-10 108 views
2

这可能是一个非常简单的问题,但自从昨晚以来似乎无法解决这个问题。SQL:从一张表中加入两个不同行的表格

我有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 

的VirtualLicense和许可使用使用产品表产品名称和产品编号映射接合。

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

所以,我的例子中数据集的结果应该是

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

我不想遍历任何这样做的表。 我希望我的问题从我的描述和数据中清楚。

回答

2

你可以做这样的事情:

  • 在第一CTE - 分配排名为产品组内VirtualLicenses。
  • 在第二个CTE中 - 为产品组中的Licensce指定排名(按期限排序)
  • 最后,只需在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