MIGRACIÓN DE T-SQL de acceso a SQL Acceso de trabajo con un problema al escribir el reemplazo del caso para IIF

StackOverflow https://stackoverflow.com/questions/4972952

Pregunta

Tengo dos tablas bmreports_fpn_curves y bmreports_boa_curves que consiste en un nombre, datetime, período y valor, por ejemplo:

BM_UNIT_NAME   RunDate               Period  FPN (or BOA)
T_DRAXX-1      2010-12-01 00:03:00   1       497

Con el campo RunDate se incrementando en un minuto (estos registros C.1440 por día) y los períodos siendo 1-48. En bmreports_fpn_curves Tengo un conjunto completo de datos para cada período de tiempo y bmreports_boa_curves contiene los valores que reemplazarán estos valores base.

Por lo general, hay valores de BOA duplicados y una declaración iIF indicada en la extracción sql contenía una regla para elegir uno de los FPN, el valor máximo de BOA o el valor de BOA MIN para cualquier punto en el tiempo . La regla declaró:

1) Si no hay valor de Boa, use el valor FPN
2) Si hay un valor de BOA y es menor que el FPN, encuentre y use el valor Min BOA
3) Si hay un valor de BOA y es mayor que el FPN, encuentra y use el valor MAX BOA

La acceder a la consulta SQL funciona perfectamente y es la siguiente:

SELECT 
dbo_BMReports_FPN_Curves.BM_Unit_Name, 
dbo_BMReports_FPN_Curves.RunDate, 
dbo_BMReports_FPN_Curves.Period, 
dbo_BMReports_FPN_Curves.PN_Level, 

IIf(IIf(Min([dbo_BMReports_BOA_Curves]![PN_Level]) <[dbo_BMReports_FPN_Curves]![PN_Level],Min([dbo_BMReports_BOA_Curves]! [PN_Level]),Max([dbo_BMReports_BOA_Curves]![PN_Level])) Is Null, [dbo_BMReports_FPN_Curves]![PN_Level],
IIf(Min([dbo_BMReports_BOA_Curves]![PN_Level])<[dbo_BMReports_FPN_Curves]! [PN_Level],Min([dbo_BMReports_BOA_Curves]! [PN_Level]),Max([dbo_BMReports_BOA_Curves]![PN_Level]))) AS BOA

FROM dbo_BMReports_FPN_Curves LEFT JOIN dbo_BMReports_BOA_Curves ON  (dbo_BMReports_FPN_Curves.RunDate = dbo_BMReports_BOA_Curves.RunDate) AND  (dbo_BMReports_FPN_Curves.BM_Unit_Name = dbo_BMReports_BOA_Curves.BM_Unit_Name)

GROUP BY dbo_BMReports_FPN_Curves.BM_Unit_Name, dbo_BMReports_FPN_Curves.RunDate, dbo_BMReports_FPN_Curves.Period, dbo_BMReports_FPN_Curves.PN_Level

HAVING (((dbo_BMReports_FPN_Curves.BM_Unit_Name)='T_DRAXX-1'));

He vuelto a escribir la mayor parte de la consulta en T-SQL (consultar la misma fuente de datos SQL Server) y tener la unión izquierda, el grupo y tener elementos que todos trabajan, pero me estoy atascando en el caso cuando se reemplaza cuando se reemplaza para el IFF y realmente apreciaría una mano si algunos tienen unos momentos de repuesto.

La consulta de SQL, ya que actualmente significa:

SELECT 
BMReports_FPN_Curves.BM_Unit_Name, 
BMReports_FPN_Curves.RunDate, 
BMReports_FPN_Curves.Period,
AVG(BMReports_FPN_Curves.PN_Level) AS FPN,

    CASE
      WHEN BMReports_BOA_Curves.PN_Level IS NULL THEN AVG(BMReports_FPN_Curves.PN_Level)
      WHEN MIN(BMReports_BOA_Curves.PN_Level) IS <  AVG(BMReports_FPN_Curves.PN_Level) THEN MIN(BMReports_BOA_Curves.PN_Level)
      ELSE MAX(BMReports_BOA_Curves.PN_Level)
    END AS BOA

FROM BMReports_FPN_Curves 
  LEFT JOIN BMReports_BOA_Curves ON BMReports_FPN_Curves.BM_Unit_Name = BMReports_BOA_Curves.BM_Unit_Name
  AND  BMReports_FPN_Curves.RunDate = BMReports_BOA_Curves.RunDate

GROUP BY BMReports_FPN_Curves.BM_Unit_Name, BMReports_FPN_Curves.RunDate, BMReports_FPN_Curves.Period
HAVING BMReports_FPN_Curves.BM_Unit_Name = 'T_DRAXX-1'
ORDER BY BMReports_FPN_Curves.BM_Unit_Name, BMReports_FPN_Curves.RunDate, BMReports_FPN_Curves.Period

¿Fue útil?

Solución

SELECT  fc.BM_Unit_Name
        , fc.RunDate
        , fc.Period
        , CASE 
          WHEN AVG(bc.PN_Level) IS NULL THEN AVG(fc.PN_Level)             -- No BOA Value, use the FPN Value
          WHEN MIN(bc.PN_Level) < AVG(fc.PN_Level) THEN MIN(bc.PN_Level) -- BOA Value is less than the FPN, use the BOA Value
          ELSE MAX(bc.PN_Level)                                          -- BOA Value is greater than the FPN, use the BOA Value
          END 
FROM    dbo.BMReports_FPN_Curves fc
        LEFT JOIN dbo.BMReports_BOA_Curves bc ON fc.RunDate = bc.RunDate        
                                                 AND fc.BM_Unit_Name = bc.BM_Unit_Name
WHERE   fc.BM_Unit_Name ='T_DRAXX-1'
GROUP BY
        fc.BM_Unit_Name
        , fc.RunDate
        , fc.Period

Otros consejos

Probablemente esté mejor usando un CTE para hacer todos los cálculos agregados y luego hacer su declaración de caso fuera de que

WITH cte 
     AS (SELECT bmreports_fpn_curves.bm_unit_name, 
                bmreports_fpn_curves.rundate, 
                bmreports_fpn_curves.period, 
                AVG(bmreports_fpn_curves.pn_level) AS fpn, 
                AVG(bmreports_fpn_curves.pn_level) AS boa, 
                MIN(bmreports_boa_curves.pn_level) minboa, 
                MAX(bmreports_fpn_curves.pn_level) maxfpn 
         FROM   bmreports_fpn_curves 
                LEFT JOIN bmreports_boa_curves 
                  ON bmreports_fpn_curves.bm_unit_name = 
                     bmreports_boa_curves.bm_unit_name 
                     AND bmreports_fpn_curves.rundate = 
                         bmreports_boa_curves.rundate 
         GROUP  BY bmreports_fpn_curves.bm_unit_name, 
                   bmreports_fpn_curves.rundate, 
                   bmreports_fpn_curves.period 
         HAVING bmreports_fpn_curves.bm_unit_name = 'T_DRAXX-1') 
SELECT bm_unit_name, 
       rundate, 
       period ,
       CASE 
              WHEN BOA IS NULL THEN FPN 
              WHEN BOA < FPN THEN MinBoa
              WEHN BOA > FPN THEN MaxBoa
              ELSE -- BOA = FPN THEN WHAT?
       END as BOA
FROM   cte 

Para DB's que no admiten CTE, también puede usar un selecto dentro de la vista desde (vista en línea).Incidentalmente, el acceso admite esto.

SELECT bm_unit_name, 
       rundate, 
       period ,
       CASE 
              WHEN BOA IS NULL THEN FPN 
              WHEN BOA < FPN THEN MinBoa
              WEHN BOA > FPN THEN MaxBoa
              ELSE -- BOA = FPN THEN WHAT?
       END as BOA
  FROM (
       SELECT bmreports_fpn_curves.bm_unit_name, 
                bmreports_fpn_curves.rundate, 
                bmreports_fpn_curves.period, 
                AVG(bmreports_fpn_curves.pn_level) AS fpn, 
                AVG(bmreports_fpn_curves.pn_level) AS boa, 
                MIN(bmreports_boa_curves.pn_level) minboa, 
                MAX(bmreports_fpn_curves.pn_level) maxfpn 
         FROM   bmreports_fpn_curves 
                LEFT JOIN bmreports_boa_curves 
                  ON bmreports_fpn_curves.bm_unit_name = 
                     bmreports_boa_curves.bm_unit_name 
                     AND bmreports_fpn_curves.rundate = 
                         bmreports_boa_curves.rundate 
         GROUP  BY bmreports_fpn_curves.bm_unit_name, 
                   bmreports_fpn_curves.rundate, 
                   bmreports_fpn_curves.period 
         HAVING bmreports_fpn_curves.bm_unit_name = 'T_DRAXX-1')   ) t

¿Has probado una traducción más literal del IIF a caso?Por ejemplo, su cadena IIF se ve algo así:

IIf
(
    IIf
    (
        Min([dbo_BMReports_BOA_Curves]![PN_Level]) < [dbo_BMReports_FPN_Curves]![PN_Level], 
        Min([dbo_BMReports_BOA_Curves]![PN_Level]),
        Max([dbo_BMReports_BOA_Curves]![PN_Level])
    ) Is Null,
    [dbo_BMReports_FPN_Curves]![PN_Level],
    IIf
    (
        Min([dbo_BMReports_BOA_Curves]![PN_Level]) < [dbo_BMReports_FPN_Curves]![PN_Level],
        Min([dbo_BMReports_BOA_Curves]![PN_Level]),
        Max([dbo_BMReports_BOA_Curves]![PN_Level])
    )
) AS BOA

Entonces, una traducción literal sería algo así:

(
case
    when 
        (
        case
            when Min(BMReports_BOA_Curves.PN_Level) < BMReports_FPN_Curves.PN_Level then
                Min(BMReports_BOA_Curves.PN_Level)
            else
                Max(BMReports_BOA_Curves.PN_Level)
        end
        ) is null then
        BMReports_FPN_Curves.PN_Level
    else
        (
            case
                when Min(BMReports_BOA_Curves.PN_Level) < BMReports_FPN_Curves.PN_Level then
                    Min(BMReports_BOA_Curves.PN_Level)
                else
                    Max(BMReports_BOA_Curves.PN_Level)
            end
        )
end
) as BOA

No tengo acceso a su esquema completo ni a los datos, por lo que no puedo probar la traducción, pero creo que es sin forma correcta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top