【问题标题】:SQL: JOIN two tables with distinct rows from one tableSQL:将两个表与一张表的不同行连接起来
【发布时间】:2013-07-08 06:31:24
【问题描述】:

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

我有 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 和 License 使用 ProductName 和 ProductId 映射结合使用 Product 表。

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

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

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

我不想为此循环遍历任何表。 我希望从我的描述和数据中可以清楚我的问题。

【问题讨论】:

    标签: sql sql-server-2008 tsql join


    【解决方案1】:

    你可以这样做:

    • 在第一个 CTE 中 - 为产品组中的 VirtualLicense 分配排名。
    • 在第二个 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 1970-01-01
      相关资源
      最近更新 更多