问题描述
我需要以下声明的帮助:
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 |
+---+---------+