Tenho tabelas com milhões (possivelmente bilhões) de linhas, então realmente preciso ser eficiente com a consulta.
Nesta consulta, estou unindo várias tabelas. O segmento em questão é:
LEFT JOIN
dbo.GCSOCTPS dbo_GCSOCTPS ON (GC_TBMED.MED_CLASS_NUM = dbo_GCSOCTPS.CLASS_NUM)
AND (GC_TBMED.MED_SOC_NUM = dbo_GCSOCTPS.SOC_NUM)
AND (GC_TBMED.MED_EFF_DATE = dbo_GCSOCTPS.EFF_DATE)
AND (GC_TBMED.MED_CANC_DATE = dbo_GCSOCTPS.CANC_DATE))
GC_TBMED
tem datas no DATE
formato, dbo_GCSOCTPS
tem datas no DATETIME
formato. Infelizmente, devido à forma como nossa empresa usa dados, não posso alterar isso.
Qual seria a maneira mais eficiente de comparar essas colunas? CAST
? CONVERT
? Já vi pessoas convertendo para o formato de texto e comparando dessa forma. Espero que alguém possa me orientar com base em sua experiência com conjuntos de dados muito grandes.
Se eu executar este bloco de código, obtenho um valor para HDHPQ:
SELECT TOP 200
HDHPQ,
SOC_NUM,
EFF_DATE,
CLASS_NUM,
CANC_DATE
FROM
dbo.GCSOCTPS
WHERE
SOC_NUM = '25521'
AND CLASS_NUM = '37'
AND CANC_DATE IS NULL;
Isto é retornado:
HDHPQ SOC_NUM EFF_DATE CLASS_NUM CANC_DATE
N 25521 2025-01-01 00:00:00.000 37 NULL
Se eu executar esse bloco de código, também receberei dados retornados:
SELECT TOP 200
MED_SOC_NUM,
MED_EFF_DATE,
MED_CLASS_NUM,
MED_CANC_DATE
FROM
[dbo].[AS_tblTBMED] GC_TBMED
WHERE
GC_TBMED.MED_SOC_NUM = '25521'
AND GC_TBMED.MED_CLASS_NUM = '37'
AND GC_TBMED.MED_CANC_DATE IS NULL;
Isso é retornado:
MED_SOC_NUM MED_EFF_DATE MED_CLASS_NUM MED_CANC_DATE
25521 2025-01-01 37 NULL
Cada um deles retorna uma linha. Preciso juntá-los para obter todos os dados da segunda consulta e o valor de HDHPQ da primeira consulta.
Então eu executo esta consulta:
SELECT DISTINCT TOP 200
dbo_GCSOCTPS.HDHPQ,
dbo_GCSOCTPS.SOC_NUM,
dbo_GCSOCTPS.EFF_DATE,
dbo_GCSOCTPS.CLASS_NUM,
dbo_GCSOCTPS.CANC_DATE,
GC_TBMED.MED_SOC_NUM,
GC_TBMED.MED_EFF_DATE,
GC_TBMED.MED_CLASS_NUM,
GC_TBMED.MED_CANC_DATE
FROM
[dbo].[AS_tblTBMED] GC_TBMED
LEFT JOIN
dbo.GCSOCTPS dbo_GCSOCTPS ON (GC_TBMED.MED_CLASS_NUM = dbo_GCSOCTPS.CLASS_NUM)
AND (GC_TBMED.MED_SOC_NUM = dbo_GCSOCTPS.SOC_NUM)
AND (GC_TBMED.MED_EFF_DATE = CAST(dbo_GCSOCTPS.EFF_DATE as DATE))
AND (GC_TBMED.MED_CANC_DATE = CAST(dbo_GCSOCTPS.CANC_DATE as DATE))
WHERE
GC_TBMED.MED_SOC_NUM = '25521'
AND GC_TBMED.MED_CLASS_NUM = '37'
AND GC_TBMED.MED_CANC_DATE IS NULL
AND dbo_GCSOCTPS.EFF_DATE >= '2025-01-01';
E um conjunto de registros vazio é retornado. Se eu comentar as duas datas na junção, obtenho dados. Portanto, presumo que os campos de data não estejam sendo equalizados corretamente, já que são iguais e, portanto, eu deveria obter dados se eles fossem incluídos na consulta.