【问题标题】:sql query help (count)sql查询帮助(计数)
【发布时间】:2014-11-01 22:29:27
【问题描述】:

我有 3 张桌子

CUSTOMERS (CUSTOMER_ID, LASTNAME, FIRSTNAME, ... other fields)
LICENSES(LICENSE_ID, CREATED_AT, RELEASE_ID, CUSTOMER_ID, ... other fields)
RELEASES(RELEASE_ID, RELEASE_NAME, RELEASE_NUMBER, ... other fields)

LICENSE 中的 CREATED_AT 是一个 DATE(非空)字段。

表根据同名的主键/外键关联;一个客户可以拥有 0 个或多个许可证,每个许可证都有一个版本。

我想从这些表中获取:

客户的名字、姓氏和最后一个创建的许可证的 release_id(根据 LICENSE 中的 CREATED_AT 字段查找最后一个)(如果有的话)。

对于这个我使用了这个查询:

SELECT CUSTOMERS.FIRSTNAME,
       CUSTOMERS.LASTNAME,

  (SELECT RELEASES.RELEASE_ID
   FROM RELEASES
   INNER JOIN LICENSES ON LICENSES.RELEASE_ID = RELEASES.RELEASE_ID
   INNER JOIN CUSTOMERS AS t ON t.CUSTOMER_ID = LICENSES.CUSTOMER_ID
   WHERE t.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID
   ORDER BY LICENSES.CREATED_AT DESC LIMIT 1) AS REL_ID
FROM CUSTOMERS
WHERE EXISTS
    (SELECT 1
     FROM RELEASES
     INNER JOIN LICENSES ON LICENSES.RELEASE_ID = RELEASES.RELEASE_ID
     INNER JOIN CUSTOMERS AS t ON LICENSES.CUSTOMER_ID = t.CUSTOMER_ID
     AND t.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID)

这似乎可行,但我问是否有人可以确认我,或者是否有可能使它更简单。

我想从这些表中获得的其他数据是 RELEASES.RELEASE_ID, RELEASES.RELEASE_NAME, RELEASES.RELEASE_NUMBER 和最后一个许可证的客户数量(根据 LICENSES 中的 CREATED_AT)有这个版本。

我无法创建此查询。 我正在使用 h2 数据库。

感谢您的帮助

【问题讨论】:

    标签: sql h2 jooq


    【解决方案1】:

    这应该是等价的

    SELECT CUSTOMERS.FIRSTNAME,
           CUSTOMERS.LASTNAME,
          (SELECT LICENSES.RELEASE_ID
           FROM LICENSES
           WHERE LICENSES.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID
           ORDER BY LICENSES.CREATED_AT DESC
           LIMIT 1) AS REL_ID
    FROM CUSTOMERS
    WHERE EXISTS (
        SELECT 1 
        FROM LICENSES
        WHERE LICENSES.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
    )
    

    如果您对LICENSES.RELEASE_ID 和LICENSES.CUSTOMER_ID 有外键约束,则不需要连接所有这些表。特别是,加入RELEASES 表毫无意义,因为LICENSES.RELEASE_ID 列已经包含所需的信息。

    LATERAL / CROSS APPLY 加入其他数据库

    为了完整起见,如果是 PostgreSQL、Oracle、SQL Server 等,您可以执行 lateral join,也称为 CROSS APPLY

    SELECT CUSTOMERS.FIRSTNAME,
           CUSTOMERS.LASTNAME,
           l.RELEASE_ID
    FROM CUSTOMERS 
    CROSS JOIN LATERAL (
        SELECT *
        FROM LICENSES
        WHERE LICENSES.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID
        ORDER BY LICENSES.CREATED_AT DESC
        LIMIT 1
    ) l
    

    【讨论】:

    • 您好,感谢您的回答和建议。我的问题包含 2 个查询,另一个在问题的最后一部分,我无法创建它。你有什么建议吗?
    • @res1:请在 Stack Overflow 上提出一个新问题。未来的访问者会更容易理解正在发生的事情......
    【解决方案2】:

    这个怎么样:

    SELECT c.FIRSTNAME, c.LASTNAME, r.RELEASE_ID
    FROM CUSTOMERS c
    INNER JOIN LICENSES l ON (c.CUSTOMER_ID = l.CUSTOMER_ID)
    INNER JOIN RELEASES r ON (r.RELEASE_ID = l.RELEASE_ID)
    
    WHERE r.CREATED_AT = ( SELECT MAX(t.CREATED_AT) FROM RELEASES t
                           WHERE t.RELEASE_ID = r.RELEASE_ID )
    

    由于内部连接,只会列出发布版本的客户。

    【讨论】:

    • 这里不需要RELEASES 表。此外,结果集中缺少RELEASE_ID(最近的LICENSES.CREATED_AT 日期)
    • 你说得对,我没有注意到那个专栏。我已经更新了上面的查询
    • 感谢您的回答,正如我在 cmets 中对 Lukas 的回答所说,我的问题包含 2 个查询,我无法创建最后一个
    猜你喜欢
    • 2010-10-20
    • 1970-01-01
    • 2023-03-23
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多