LEFT JOIN在静态项目列表上?

时间:2016-10-21 14:54:35

标签: sql join left-join intersystems-cache

DBMS是

动机:我需要在表上进行左连接,这样每次都可以获得相同的消息类型列表,即使结果为零或为null。不幸的是,这是一张大表,因此包含SELECT DISTINCT()的速度非常慢。这些永远不会改变,所以我想我会得到一次列表,然后静态地加入它们。

基于另一个SO问题,我需要替换SELECT DISTINCT()

    SELECT 'HS.MESSAGE.GATEWAYREGISTRATIONREQUEST' as MessageBodyClassName
    UNION SELECT 'HS.MESSAGE.MERGEPATIENTREQUEST'
    UNION SELECT 'HS.MESSAGE.PATIENTSEARCHREQUEST'

这将返回完全符合预期的结果,与Distinct查询相同。但是,当我将其插入到JOIN语句中时,所有计数都会返回零。

查询失败

SELECT mh.MessageBodyClassName, count(l.MessageBodyClassName) as MessageCount FROM 
    (
        SELECT 'HS.MESSAGE.GATEWAYREGISTRATIONREQUEST' as MessageBodyClassName
        UNION SELECT 'HS.MESSAGE.MERGEPATIENTREQUEST'
        UNION SELECT 'HS.MESSAGE.PATIENTSEARCHREQUEST'
    ) mh LEFT JOIN
    (
        SELECT messageBodyClassName FROM ens.messageheader WHERE TimeCreated > DATEADD(hh, -1, GETUTCDATE())
    ) l ON mh.MessageBodyClassName = l.MessageBodyClassName
GROUP BY mh.MessageBodyClassName

结果失败

MessageBodyClassName                  MessageCount 
------------------------------------- ------------ 
HS.MESSAGE.GATEWAYREGISTRATIONREQUEST 0            
HS.MESSAGE.MERGEPATIENTREQUEST        0            
HS.MESSAGE.PATIENTSEARCHREQUEST       0

工作查询

SELECT mh.MessageBodyClassName, count(l.MessageBodyClassName) as MessageCount FROM 
    (
        SELECT DISTINCT(MessageBodyClassName) FROM ens.messageheader
    ) mh LEFT JOIN
    (
        SELECT messageBodyClassName FROM ens.messageheader WHERE TimeCreated > DATEADD(hh, -1, GETUTCDATE())
    ) l ON mh.MessageBodyClassName = l.MessageBodyClassName
GROUP BY mh.MessageBodyClassName

工作和预期结果

MessageBodyClassName                  MessageCount 
------------------------------------- ------------ 
HS.MESSAGE.GATEWAYREGISTRATIONREQUEST 0            
HS.MESSAGE.MERGEPATIENTREQUEST        0            
HS.MESSAGE.PATIENTSEARCHREQUEST       54

对于VKP:为什么结果不同?如何使用文字调整第一个查询以获得正确(相同)的结果?

2 个答案:

答案 0 :(得分:1)

我能想到的最后一件事是将DISTINCT查询一次运行到数据库中的永久表中。这样,查询中的内部SELECT只需要处理这三行。内部查询将丢失DISTINCT,如

SELECT MessageBodyClassName FROM ens.messageheader_permvals

编辑:以下答案无效

这可能是一个远景,但如果它不起作用,它可能会帮助您诊断问题。而不是UNION尝试

SELECT MessageBodyClassName FROM ens.messageheader
    WHERE MessageBodyClassName in (
    'HS.MESSAGE.GATEWAYREGISTRATIONREQUEST',        
    'HS.MESSAGE.MERGEPATIENTREQUEST',          
    'HS.MESSAGE.PATIENTSEARCHREQUEST')

只有当这些值实际存在于表中且与我们知道使用MessageBodyClassName版本工作的DISTINCT格式兼容时,才会返回记录。我不知道这种表现是否会更好,但希望它会对这个问题有所了解。

编辑:以下答案不适用,因为OP实际上是在尝试选择文字引用值

您的UNION查询中没有FROM个语句。尝试

SELECT 'HS.MESSAGE.GATEWAYREGISTRATIONREQUEST' as MessageBodyClassName
            FROM ens.messageheader
        UNION SELECT 'HS.MESSAGE.MERGEPATIENTREQUEST'
            FROM ens.messageheader
        UNION SELECT 'HS.MESSAGE.PATIENTSEARCHREQUEST'
            FROM ens.messageheader

查询的其余部分看起来正确。

答案 1 :(得分:0)

我同意xQbert,问题是硬代码值

尝试

  SELECT T1.MessageBodyClassName, T2.MessageBodyClassName
  FROM (
          SELECT 'HS.MESSAGE.GATEWAYREGISTRATIONREQUEST' as MessageBodyClassName
    UNION SELECT 'HS.MESSAGE.MERGEPATIENTREQUEST'
    UNION SELECT 'HS.MESSAGE.PATIENTSEARCHREQUEST'
       ) as T1
 LEFT JOIN (
         SELECT DISTINCT(MessageBodyClassName) as MessageBodyClassName
         FROM ens.messageheader
       ) as T2
  ON T1.MessageBodyClassName = T2.MessageBodyClassName

可能的解决方案:创建时态表

 CREATE TABLE className as 
         SELECT DISTINCT(MessageBodyClassName) as MessageBodyClassName
         FROM ens.messageheader