sql查询帮助(计数)

时间:2014-09-08 16:21:52

标签: sql h2 jooq

我有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,并且持有许可证的客户数量(根据许可证中的CREATED_AT)具有此版本。

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

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

这个怎么样:

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 )

由于内部联接,仅列出具有发布的客户。

答案 1 :(得分: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_IDLICENSES.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