繁体   English   中英

FIND_IN_SET 相当于 SQL 带 IF 条件的服务器

[英]FIND_IN_SET equivalent to SQL Server with IF Condition

我需要以下声明的帮助:

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

我尝试了各种解决方案,但无法在 SQL 服务器中重现相同的场景。

下面,我将把所有 select(在 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,
         concat(m.iCodEmpresa, '|',  m.iCodFranqueado)                                        as empresa_pk, 
         if( FIND_IN_SET(m.iCodFormaPgto, p.cValor) > 0, 'Delivery', 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.iCodLoja,
         m.cCodPDV,
         m.iCodSegmento,
         m.iCodFranqueado,
         m.iCodFormaPgto,
         m.cFormaPgto,
         m.iCodEmpresa,
         p.cValor

我在 SQL 服务器上创建的最后一个 select,就是下面这个。 但最终会报错,因为子查询返回的值不止一个:

        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(',',tmp_p.cValor,',') like concat('%,',tmp_m.iCodFormaPgto,',%')
                )
            )
        ) as x
        ) when 'Delivery' then 'Delivery' else cNome END as fato_vnd_seg_virtual

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

在所示的 SQL 代码中,此 function 仅检查指定值是否存在于 CSV 值列表中(函数返回值的 position,但它仅用于存在性检查)。 所以你可以,例如,使用

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

扩展@Akina,完整的 SQL 服务器查询将是:

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(','+p.cValor+',', ','+m.iCodFormaPgto+',') > 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.iCodFranqueado, '|', 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 |
+---+---------+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM