FIND_IN_SET等效于具有IF条件的SQL Server

问题描述

我需要以下声明的帮助:

if( FIND_IN_SET(m.iCodFormaPgto,p.cValor) > 0,'Delivery',seg.CNome) as fato_vnd_seg_virtual

我尝试了各种解决方案,但无法在SQL Server中重现相同的情况。

下面,我将所有选择(在MySQL上运行)

SELECT  'dia_pgto_pdv'                        as fato_tipo_ds,FORMAT(m.dtMovimento,'%Y%m%d')      as periodo_pk,concat(m.iCodEmpresa,'|',m.iCodFranqueado,m.iCodLoja )                       as loja_pk,concat(m.iCodLoja,m.cCodPDV)                                                  as pdv_pk,concat(m.iCodFranqueado,m.iCodEmpresa,m.iCodLoja,m.iCodSegmento)    as segmento_pk,m.iCodFranqueado                                                                     as franqueado_pk,m.iCodFormaPgto                                                                      as forma_pgto_pk,m.cFormaPgto                                                                         as forma_pgto_ds,m.iCodFranqueado)                                        as empresa_pk,if( FIND_IN_SET(m.iCodFormaPgto,seg.CNome)               as fato_vnd_seg_virtual,SUM(m.deValor)                       as fato_vnd_valor,SUM(m.iGC)                           as fato_vnd_igc
FROM  md_stage.dbo.mov_dia_pgto_pdv m
left join   md_stage.dbo.segmento seg ON seg.iCodSegmento = m.iCodSegmento and
                                        seg.iCodLoja     = m.iCodLoja
JOIN md_stage.dbo.params p ON p.cIdParam = 'VENDA_FORMA_PAGAMENTO_TIPOS_DELIVERY'
GROUP BY m.dtMovimento,m.cCodPDV,m.iCodSegmento,m.iCodFormaPgto,m.cFormaPgto,p.cValor

我在SQL Server中创建的最后一个选择是下面的选择。但这最终会导致错误,因为子查询返回多个值:

        case
        (select cNome from (    
            (select
                    tmp_m.iCodFormaPgto,'Delivery' as cNome
                 from md_stage.dbo.mov_dia_pgto_pdv tmp_m
                 where exists (
                    select 
                        tmp_p.cValor
                    from md_stage.dbo.params tmp_p
                    where concat(',',tmp_p.cValor,') like concat('%,tmp_m.iCodFormaPgto,%')
                )
            )
            UNION ALL
            (select
                    tmp_m.iCodFormaPgto,tmp_seg.cNome
                 from md_stage.dbo.mov_dia_pgto_pdv tmp_m
            left join   md_stage.dbo.segmento tmp_seg ON tmp_seg.iCodSegmento = tmp_m.iCodSegmento and
                                                     tmp_seg.iCodLoja     = tmp_m.iCodLoja
                 where not exists (
                    select 
                        tmp_p.cValor
                    from md_stage.dbo.params tmp_p
                    where concat(',%')
                )
            )
        ) as x
        ) when 'Delivery' then 'Delivery' else cNome END as fato_vnd_seg_virtual

解决方法

MySQL函数FIND_IN_SET()在SQL Server中没有直接的模拟。使用一些表达式。

在所示的SQL代码中,此函数仅检查CSV值列表中是否存在指定的值(该函数返回值的位置,但仅用于状态检查)。因此,例如,您可以使用

CASE WHEN CHARINDEX(','+p.cValor+',','+m.iCodFormaPgto+',') > 0
     THEN 'Delivery'
     ELSE seg.CNome
     END AS fato_vnd_seg_virtual
,

扩展@Akina,完整的SQL Server查询将是:

SELECT
    'dia_pgto_pdv' as fato_tipo_ds,--
    format(m.dtMovimento,120) as periodo_pk,--
    ... as loja_pk,... as pdv_pk,... as segmento_pk,--
    m.iCodFranqueado as franqueado_pk,m.iCodFormaPgto  as forma_pgto_pk,m.cFormaPgto     as forma_pgto_ds,...               as empresa_pk,--
    CASE
        WHEN CHARINDEX(',') > 0
            THEN 'Delivery'
            ELSE seg.CNome
    END AS fato_vnd_seg_virtual,--
    SUM(m.deValor) as fato_vnd_valor,SUM(m.iGC)     as fato_vnd_igc
FROM
    md_stage.dbo.mov_dia_pgto_pdv m
        --
        left join md_stage.dbo.segmento seg
        ON seg.iCodSegmento = m.iCodSegmento and
           seg.iCodLoja     = m.iCodLoja
        --
        JOIN md_stage.dbo.params p
        ON p.cIdParam = 'VENDA_FORMA_PAGAMENTO_TIPOS_DELIVERY'
GROUP BY m.dtMovimento,m.iCodLoja,m.cCodPDV,m.iCodSegmento,m.iCodFranqueado,m.iCodFormaPgto,m.cFormaPgto,m.iCodEmpresa,p.cValor

...代表concat,在SQL Server中有些复杂,例如:

concat(m.iCodEmpresa,'|',m.iCodLoja)

应写为:

convert(varchar,m.iCodEmpresa) + '|' +
convert(varchar,m.iCodFranqueado) + '|' +
convert(varchar,m.iCodLoja)
,

您可以使用OUTER APPLY来检查另一个表中是否存在特定值。


SELECT t.i,ISNULL(FindInSet.Result,0) As IsExist
FROM 
(
values
(1),(2)
) as t(i)
OUTER apply
(
SELECT 1 FROM 
(values
(1),(5),(7)
) as f(totalset)
WHERE f.totalset = t.i
) AS FindInSet(result)


+---+---------+
| i | IsExist |
+---+---------+
| 1 |       1 |
| 2 |       0 |
+---+---------+

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...