特殊左连接

izkcnapc  于 2021-06-26  发布在  Impala
关注(0)|答案(2)|浏览(200)

我有下面的sql(impala)伪查询,因为它不会以这种方式编译。有趣的是最后一部分,我想做你能读到的。
我想做一个左连接,但如果没有匹配的productid,我想使用一个特定的productid(它是空的,假设只有一个,但通过使用limit 1来保证它),并执行一个类似连接的连接,这样在这种情况下上述条件将正常工作。
所以基本上问题是,如果有办法把这个语法错误的查询转换成一个正确的查询?
我尝试了不同的方法,例如isnull()和with,但是由于您在else部分看到的子查询必须使用两个表才能正常工作,因此无论如何都无法编译它,我认为它可以正常工作。

SELECT 
    cd.CycleDataId AS CycleDataId,
    CASE   
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime <= op.MaxValue THEN NVL(dcl.ProductionLossTypeId, -1)
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime >= op.MaxValue THEN dcl.ProductionLossTypeId
    END AS Verdikt,
    CASE   
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime <= op.MaxValue THEN NVL(dcl.Time, cd.CycleTime - op.IdealValue)
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime >= op.MaxValue THEN dcl.Time  
    END AS Time
FROM CycleData cd
LEFT JOIN DistributedCycleLosses dcl ON dcl.CycleDataId = cd.CycleDataId
CASE   
WHEN IF EXISTS(SELECT * FROM Operation_parameter WHERE ProductId = cd.ProductId AND cd.Timestamp_ BETWEEN ValidFrom AND ValidTo) THEN LEFT JOIN Operation_parameter op ON op.ProductId = cd.ProductId AND cd.Timestamp_ BETWEEN op.ValidFrom AND op.ValidTo
ELSE (SELECT * FROM Operation_parameter WHERE ProductId IS NULL AND cd.Timestamp_ BETWEEN ValidFrom AND ValidTo LIMIT 1) AS op
END;
thtygnil

thtygnil1#

这基本上是使用默认值。我想这正是你想要的:

SELECT cd.CycleDataId AS CycleDataId,
        (CASE WHEN cd.CycleTime >= COALESCE(op.IdealValue, opnull.IdealValue) AND 
                   cd.CycleTime <= COALESCE(op.MaxValue, opnull.MaxValue) 
              THEN COALESCE(dcl.ProductionLossTypeId, -1)
              WHEN cd.CycleTime >= COALESCE(op.IdealValue, opnull.IdealValue) AND
                   COALESCE(op.MaxValue, opnull.MaxValue)
              THEN dcl.ProductionLossTypeId
         END) AS Verdikt,
        (CASE WHEN cd.CycleTime >= COALESCE(op.IdealValue, opnull.IdealValue) AND
                   cd.CycleTime <= COALESCE(op.MaxValue, opnull.MaxValue)
              THEN cd.CycleTime >= COALESCE(dcl.Time, cd.CycleTime - COALESCE(op.IdealValue, opnull.IdealValue))
              WHEN cd.CycleTime >= COALESCE(op.IdealValue, opnull.IdealValue) AND
                   cd.CycleTime >= COALESCE(op.MaxValue, opnull.MaxValue)
              THEN dcl.Time  
         END) AS Time
FROM CycleData cd LEFT JOIN 
     DistributedCycleLosses dcl
     ON dcl.CycleDataId = cd.CycleDataId LEFT JOIN
     Operation_parameter op
     ON op.ProductId = cd.ProductId AND
        cd.Timestamp_ BETWEEN op.ValidFrom AND op.ValidTo LEFT JOIN
     Operation_parameter opnull
     ON op.ProductId IS NULL AND  -- no previous match
        opnull.ProductID IS NULL AND
        cd.Timestamp_ BETWEEN opnull.ValidFrom AND opnull.ValidTo ;

请注意,所有引用 op 替换为 COALESCE() 表达。
您可以修改它来处理多行匹配 NULL 价值观,如果真的有必要的话。我认为逻辑中更重要的部分是 LEFT JOIN s。

falq053o

falq053o2#

为整个实体设置默认值有点棘手,但对于字段列表,可以这样实现:

SELECT 
    cd.CycleDataId AS CycleDataId, ISNull(op.[parameterName],'default parameter value') as [parameterName]
    CASE   
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime <= op.MaxValue THEN NVL(dcl.ProductionLossTypeId, -1)
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime >= op.MaxValue THEN dcl.ProductionLossTypeId
    END AS Verdikt,
    CASE   
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime <= op.MaxValue THEN NVL(dcl.Time, cd.CycleTime - op.IdealValue)
        WHEN cd.CycleTime >= op.IdealValue AND cd.CycleTime >= op.MaxValue THEN dcl.Time  
    END AS Time
FROM CycleData cd
LEFT JOIN DistributedCycleLosses dcl ON dcl.CycleDataId = cd.CycleDataId,
LEFT JOIN Operation_parameter op ON op.ProductId = cd.ProductId AND cd.Timestamp_ BETWEEN op.ValidFrom AND op.ValidTo

相关问题