¿Cómo devolver conjuntos de valores basados ​​en la condición en SQL Server 2005?

Soy un principiante en el procedimiento almacenado de SQL Server 2005. Parece que no puedo hacer que funcione como quería.

Tengo un sp que toma el parámetro @caseid de una tabla llamada annot. @caseid se asigna al valor de la columna src_caseid y puede tener varias referencias (ref_caseid) o ninguno en la tabla annot. Quiero establecer una condición y establecer la bandera shepards adecuada dependiendo de la columna court de la mesa case que hice usando INNER JOIN.

Básicamente este es el escenario:

  • Mesa annot - ref_caseid, src_caseid, annotation
  • Mesa case - caseid, court

Ejemplo de conjunto de resultados de INNER JOIN en ref_caseid = caseid Me gusta esto:

ref_caseid   src_caseid   annotation    court
  17334         17338        Refd       high court
  17600         17338        Foll       federal court
  18271         17338        Foll       federal court
  43220         17338        Not Foll   supreme court

Condición a establecer:

Del conjunto de registros, si federal court existe, solo debe tomar filas de federal court. Si no federal court se encuentra, entonces tomará otros casos con otros valores judiciales.

Para lograr esto, configuré un contador para federal court cuenta Pero parece que SQL solo lee la última fila y establece @courtFC valor basado en él. He intentado order by pero no parece funcionar tan bien.

Del ejemplo anterior, el valor final de shepardsflag del caso 17338 debe ser = 3 (Foll), ya que debe tomar filas con "tribunal federal" solo E ignorar el resto de las filas.

Pero el resultado actual es shepardsflag = 2 ; Cuál está mal

Espero explicarme bien.

¿Alguien puede ayudarme con la lógica correcta? ¿Debo crear una tabla temporal? Gracias por adelantado.

Guión:

ALTER PROCEDURE [dbo].[spUpdateShepardsFlags] @caseid int = null AS
begin
declare @Shep int
declare @ref_caseid int
declare @court int
declare @courtFC int
declare @annot int

if @caseid is not null
   begin
      select @court = b.court, @ref_caseid = a.ref_caseid, @annot = a.annotation
         from cba_annot a inner join cbm_case b on a.ref_caseid = b.caseid 
         where a.src_caseid = @caseid

      if @court is not null
        begin
           if @court = 'MYFC'
              set @courtFC = @courtFC + 1
           if @court <> 'MYFC'
              SET @courtFC = @courtFC + 0
            PRINT 'The @courtFC counter : ' + CAST(@courtFC AS CHAR) 
        end

        if @court is not NULL 
        begin
          if @courtfc > 0
           begin 
             if exists(select a.ref_caseid, b.court, a.annotation, a.src_caseid from 
                       cba_annot a inner join cbm_case b on a.ref_caseid = b.caseid)
                begin
                   if exists(select src_caseid from cba_annot where (annotation like '%Refd%'
                      or annotation like '%Comp%')
                      and src_caseid = @caseid)
                      set @Shep = 4

                   if exists(select src_caseid from cba_annot where (annotation like '%Foll%'
                      or annotation like '%Aff%')
                      and src_caseid = @caseid)
                      set @ShepFC = 3

                    update cbm_case
                    set shepardsflag = @shep
                    where caseid=@caseid
                end
            end

          else -- if @courtFC = 0
            begin --new
             if exists(select a.ref_caseid, b.court, a.annotation, a.src_caseid from 
                       cba_annot a inner join cbm_case b on a.ref_caseid = b.caseid)
                begin
                   if exists(select src_caseid from cba_annot where (annotation like '%Refd%'
                      or annotation like '%Comp%')
                      and src_caseid = @caseid)
                      set @Shep = 4

                   if exists(select src_caseid from cba_annot where (annotation like '%Foll%'
                      or annotation like '%Aff%')
                      and src_caseid = @caseid)
                      set @Shep = 3

                   if exists(select src_caseid from cba_annot where (annotation like '%Not Foll%'
                      or annotation like '%Dist%')
                      and src_caseid = @caseid)
                      set @Shep = 2

                    update cbm_case
                    set shepardsflag = @shep
                    where caseid=@caseid
                end

          end -- new
      end
  else  --- if court is NULL -- case not referred by any other case
        update cbm_case
        set shepardsflag = 5
        where caseid=@caseid
  end 

else -- if caseid is null

-- other condition

preguntado el 04 de julio de 12 a las 09:07

¿Obtuviste una respuesta para esto? -

1 Respuestas

Tiene algunos problemas reales con su comprensión de SQL y dudo seriamente que las tablas temporales sean relevantes.

1) Las variables se inicializan como nulas, pero eso no parece haberlo estropeado significativamente. (@courtFC + 0 no te evalúa de la forma en que probablemente estabas pensando).

2) La forma en que estaba haciendo las tareas depende del orden y el último gana exactamente como lo notó. En lugar de decir:

select @court = b.court, ...

Podrías haber usado esto:

select @courtFC = count(b.court) ... where b.court = 'federal court'

También parece que estás tratando de escribir un bucle y creo que esa es otra parte de tu confusión. SQL se trata de conjuntos, que operan en varias filas a la vez.

3) A todas sus subconsultas EXISTS en los bloques internos les faltan filtros en el caseid relevante.

Su enfoque en realidad podría funcionar solo con esos cambios.

Mi versión aquí no pretende complicar las cosas, pero me temo que tendrá problemas con ella. Aquí hay una solución basada en conjuntos que realmente es una forma más natural.

if @caseid is not null /* short-circuit the update, but probably not necessary */
update cbm_case
set shepardsflag = coalesce(
    (
    select
        case
            max( /* highest precendence wins */
                case /* map annotations by precedence i.e. */
                     /* if there are multiple annotations, */
                     /* which one takes priority */
                    when a.annotation in ('Refd', 'Comp')     then 'P1'
                    when a.annotation in ('Foll', 'Aff')      then 'P2'
                    when a.annotation in ('Not Foll', 'Dist') then 'P3'
                    else cast(0/0 as char(2)) /* error, I think */
                end
            )
            when 'P1' then 4 /* translate back to shepardsflag */
            when 'P2' then 3
            when 'P3' then 2
        end
    from
        cba_annot as a inner join cbm_case as refcase
            on refcase.caseid = a.ref_caseid
    where
        a.src_caseid = cbm_case.caseid
        and (
            cbm_case.court <> 'federal court'  /* all if src case not federal */
            or refcase.court = 'federal court' /* always get federal */
        )
    ),
    5
)
where caseid = @caseid;

Editar 2 Ignora mi comentario en 3). Mirando de nuevo, creo que había leído mal el código de OP debido al paréntesis y al salto de línea.

Editar 3 Se corrigió el error causado por la falta del carácter @ en la primera línea.

Respondido 24 Jul 12, 07:07

Muchas gracias por esto. Pero encontré una tabla temporal de solución: INSERTAR EN #corte (ref_caseid, src_caseid, tribunal, anotación) SELECCIONAR ref_caseid, src_caseid, tribunal, anotación DESDE (SELECCIONAR a.ref_caseid, b.court, a.annotation, a.src_caseid , RANK() SOBRE (PARTICIÓN POR a.src_CaseID ORDEN POR CASO CUANDO b.court = 'MYFC' THEN 1 ELSE 2 END) COMO Fila DESDE cba_annot a INNER JOIN cbm_case b ON a.ref_caseid = b.caseid WHERE a.src_caseid = 17338) Derivado DONDE fila = 1 - user1500714

Sus datos de muestra muestran que puede haber varios casos de referencia de tribunales federales, por lo que tiene vínculos en RANK() y, por lo tanto, varias filas con ROW = 1. Supongo que usa esa tabla temporal como parte de su lógica para determinar si existe una fila 'MYFC' y que solo le importa la columna de la corte . Entonces, parece que usó una tabla temporal y una función RANK donde realmente podría haber hecho un ORDER BY en su expresión de caso en primer lugar. Y todavía está usando más de diez SELECCIONES y ACTUALIZACIONES donde podría usar una siguiendo el enfoque conjunto que sugerí. - shawnt00

Hola, pruebo tu enfoque sugerido pero está dando un error de sintaxis en la última línea ';'. Intenté varios cambios pero todavía arroja el error de sintaxis. ¿Puede alguien por favor ayudar? Gracias un montón. - user1500714

@ user1500714 Podría estar en la primera línea. Debiera ser if @caseid en lugar de if caseid - shawnt00

user150714 Proporcione los detalles del mensaje de error y el método que está utilizando para probarlo. - shawnt00

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.