问题:
我最近遇到了一个有趣的 SQL 问题。
我必须获得租赁对象的租赁合同。
问题是,每个房间可能有多个租赁合同,每个房间可能有多个租赁对象。
但是,由于糟糕的数据库修补,租赁合同被分配给房间,而不是租赁对象。因此,我不得不将合同编号与租赁对象编号进行比较,以获得正确的结果。
我以为这样可以:
SELECT *
FROM T_Room
LEFT JOIN T_MAP_Room_LeasingObject
ON MAP_RMLOBJ_RM_UID = T_Room.RM_UID
LEFT JON T_LeasingObject
ON LOBJ_UID = MAP_RMLOBJ_LOBJ_UID
LEFT JOIN T_MAP_Room_LeasingContract
ON T_MAP_Room_LeasingContract.MAP_RMCTR_RM_UID = T_Room.RM_UID
LEFT JOIN T_Contracts
ON T_Contracts.CTR_UID = T_MAP_Room_LeasingContract.MAP_RMCTR_CTR_UID
AND T_Contracts.CTR_No LIKE ( ISNULL(T_LeasingObject.LOBJ_No, '') + '.%' )
WHERE ...
但是,由于映射表在我获得合同号之前就已加入,并且没有映射表就无法获得合同号,因此我将条目翻了一番。
问题有点复杂,因为没有租赁合同的房间也需要出现,所以我不能只使用内部连接。
通过一些实验,我发现这可以按预期工作:
SELECT *
FROM T_Room
LEFT JOIN T_MAP_Room_LeasingObject
ON MAP_RMLOBJ_RM_UID = T_Room.RM_UID
LEFT JON T_LeasingObject
ON LOBJ_UID = MAP_RMLOBJ_LOBJ_UID
LEFT JOIN T_MAP_Room_LeasingContract
LEFT JOIN T_Contracts
ON T_Contracts.CTR_UID = T_MAP_Room_LeasingContract.MAP_RMCTR_CTR_UID
ON T_MAP_Room_LeasingContract.MAP_RMCTR_RM_UID = T_Room.RM_UID
AND T_Contracts.CTR_No LIKE ( ISNULL(T_LeasingObject.LOBJ_No, '') + '.%' )
WHERE ...
我现在明白了为什么一个连接中的两个 on 条件(通常由查询设计器提供)可能有用,以及它有什么不同。
我想知道这是否是 MS-SQL/T-SQL 特定的东西,或者这是否是标准 sql。
所以我在 PostgreSQL 中尝试了另外 3 个表。
所以我在其他 3 个表上写了这个查询:
SELECT *
FROM t_dms_navigation
LEFT JOIN t_dms_document
ON NAV_DOC_UID = DOC_UID
LEFT JOIN t_dms_project
ON PJ_UID = NAV_PJ_UID
并试图在条件下将其变成一个有两个
SELECT *
FROM t_dms_navigation
LEFT JOIN t_dms_document
LEFT JOIN t_dms_project
ON PJ_UID = NAV_PJ_UID
ON NAV_DOC_UID = DOC_UID
所以我认为它是 t-sql 特定的,但很快也在 MS-SQL 中尝试过,只是让我惊讶地发现它在那里也不起作用。
我认为这可能是因为缺少外键,所以我在房间查询中的所有表上删除了它们,但它仍然不起作用。
所以在这里我的问题
是:为什么 2 在条件下甚至是合法的,这有名字吗,为什么它在我的第二个例子中不起作用?