我不确定如何最好地描述我遇到的问题,但它感觉非常像SQL查询需要一个超前条件,例如正则表达式中的那些条件:)。请原谅我的冗长,因为我试图找到表达这个问题的方法。
我有一个相对复杂的医疗服务模式,患者信息,患者支付类型(包括保险,工人信息等)和医疗销售佣金收入。当然还有销售报告工具。以下是涉及不同JOIN
条件情况的查询的过度简化版本。这个查询的大多数只是我的问题所关注的子句的上下文,倒数第二个WHERE
条件(定义{{1}}条件):
JOIN
同样,这非常简单:SELECT vendor_services.*, patients.*, payments.*, vendor_products.*, products.*, vendor_product_commissions.*, vendor_commissions.*, commission_earners.*, users.*
FROM vendor_services
JOIN patients ON patients.vendor_id = vendor_services.vendor_id
JOIN payments ON payments.patient_id = patiends.id
JOIN payment_types ON payment_types.id = payments.payment_type_id
JOIN vendor_products ON vendor_products.id = vendor_services.vendor_product_id
JOIN products ON products.id = vendor_products.product_id
JOIN vendor_product_commissions ON vendor_product_commissions.vendor_product_id = vendor_products.id
JOIN vendor_commissions ON vendor_commissions.id = vendor_product_commissions.vendor_commissions.id
LEFT JOIN commission_earners ON commission_earners.id = vendor_commissions.commission_earners_id
JOIN users ON commission_earners.user_id = users.id
WHERE
vendor_services.state != 'In Progress'
AND
vendor_services.date BETWEEN :datetime_1 AND :datetime_2
AND
vendor_commissions.start_date > :datetime_1
AND
vendor_commissions.end_date < :datetime_2
AND
vendor_product_commissions.payment_type = payment_types.type
AND
payments.transaction_type = 'Paid'
GROUP BY
....
子句要复杂得多,SELECT
和GROUP BY
子句,执行ORDER
语句和聚合计算等等都要复杂得多我遗漏了许多代表整个应用程序中其他系统的其他表,并且只关注相关的数据和子句。 我的问题是关于以下CASE
对此特定WHERE
条件的必要更改:
JOIN
引入了一个新的WHERE ... AND vendor_product_commissions.payment_type = payment_types.type
值,该值不是vendor_product_commissions.payment_type
值的成员。完全按照SQL查询,在大多数情况下它不再选择行,因为LEFT表将使用这个新值。添加payment_types.type
子句时,如果只选择一行,则选择重复行:
OR
我需要的是仅在WHERE ... AND vendor_product_commissions.payment_type = payment_types.type OR vendor_product_commissions.payment_type = 'DEFAULTVALUE'
的行JOIN
,除非生成{{ 1}},在这种情况下,我需要在vendor_product_commissions.payment_type = payment_types.type
上执行NULL
。
我可以使用围绕此查询的ORM代码以编程方式执行此操作,但对于非常大的报表系统来说效率非常低(实质上,首先查询特定类型,如果没有返回,则再次查询&#34;默认&#34;类型)。
我不相信PostgreSQL中存在此功能,但这就是为什么我将其描述为&#34;前瞻JOIN&#34;问题 - 我需要有一种JOIN
语句,如果第一个vendor_product_commissions.payment_type = 'DEFAULTVALUE'
条件产生CASE
关系,则执行后续JOIN
(NULL
)条件匹配此新引入的值(JOIN
)。这可以在原始SQL中完成吗?或者我是否需要将整个查询分开并执行OR
和相关数据的选择,然后以编程方式/迭代方式将其(通过ORM /应用程序语言代码)与销售佣金数据相关联?我有一个强烈的预感,可以修改查询来执行此操作,但是如果不了解此问题的特定标签或术语,我很难搜索可能的基于SQL的解决方案。
这是针对使用ActiveRecord的Ruby on Rails 4应用程序,尽管'DEFAULTVALUE'
语句都是明文/字符串,因为AR不提供services
的方法(同样,有越来越多的类型SQL JOIN
个陈述,而不是上面列出的陈述。我不确定Rails是否与我的问题相关,但我想我会提到它。