Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

Order by / Case

Estas en el tema de Order by / Case en el foro de SQL Server en Foros del Web. Gente, tengo la siguiente consulta SQL: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código SQL: Ver original SELECT RXFAM1 , RXFAM2 , RXFAM3 , PSPREC , VMVNNM     FROM ...
  #1 (permalink)  
Antiguo 05/06/2013, 14:01
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Order by / Case

Gente, tengo la siguiente consulta SQL:

Código SQL:
Ver original
  1. SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM
  2.     FROM
  3.     (SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM, ROW_NUMBER()
  4.     OVER
  5.     (ORDER BY
  6.     -- Orden x marca
  7.     CASE WHEN @marc = 'ok'
  8.     THEN VMVNNM END ASC,
  9.     -- Orden x precio descendente
  10.     CASE WHEN @prc = 'desc'
  11.     THEN PSPREC END DESC,
  12.     -- Orden x precio ascendente
  13.     CASE WHEN @prc = 'asc'
  14.     THEN PSPREC END ASC
  15.     )
  16.     AS Recursos
  17.     FROM dbo.Recursos WHERE CPA01 LIKE  '%' + @palabra + '%')
  18.     AS Resultados
  19.     WHERE Recursos BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)

Hasta aqui todo bien. Esta consulta busca los registros correspondientes mediante un LIKE en la base de datos, los pagina y los ordena mediante el ORDER BY.
En un store procedure comun esto funcionaba bien, pero cuando lo quiero implementar dentro del string en un sp_executesql me arroja el siguiente error:

"Se especificó una expresión no booleana en un contexto donde se esperaba una condición, cerca de 'Recursos'"

Noto que el error esta en los CASES del ORDER BY, cuando dejo uno solo la consulta funciona bien.
Intente cambiar la sentencia decenas de veces pero no consigo que funcione.
Alguna sugerencia, que puede estar mal?
  #2 (permalink)  
Antiguo 05/06/2013, 14:41
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

puedes poner tu codigo cuando realizas el string?
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 06/06/2013, 07:03
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Cita:
Iniciado por Libras Ver Mensaje
puedes poner tu codigo cuando realizas el string?
Código SQL:
Ver original
  1. ALTER PROCEDURE [dbo].[bus_pal]
  2.     -- Add the parameters for the stored procedure here
  3.     @clave NVARCHAR(50),
  4.     @PageNumber INT,
  5.     @marc NVARCHAR(50) = NULL,
  6.     @prc NVARCHAR(50) = NULL
  7.    
  8. AS
  9. BEGIN
  10.     -- SET NOCOUNT ON added to prevent extra result sets from
  11.     -- interfering with SELECT statements.
  12.     SET NOCOUNT ON;
  13.  
  14.     -- Insert statements for procedure here
  15.     DECLARE @SQLString NVARCHAR(500)
  16.     DECLARE @ParmDefinition NVARCHAR(500)
  17.  
  18.     /* Cadena */
  19.     SET @SQLString = N'SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM FROM (SELECT RXFAM1, RXFAM2, RXFAM3, RXFAM4, PSPREC, VMVNNM, ROW_NUMBER() OVER (ORDER BY CASE WHEN @marc = ''ok'' THEN VMVNNM END ASC, CASE WHEN @prc = ''desc'' THEN PSPREC END DESC, CASE WHEN @prc = ''asc'' THEN PSPREC END ASC) AS Recursos FROM Recursos WHERE CPA01 LIKE  @clave + ''%'') AS Resultados WHERE Recursos BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)'
  20.     /* Formato del/los parámetros */
  21.     SET @ParmDefinition = N'@clave NVARCHAR(50),@PageNumber INT,@marc NVARCHAR(50),@prc NVARCHAR(50)'
  22.  
  23.     EXEC sp_executesql @SQLString, @ParmDefinition, @clave, @PageNumber, @marc, @prc;
  24.  
  25. END
  #4 (permalink)  
Antiguo 06/06/2013, 08:17
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

creo que te falta un parentesis cerca del like...
Código SQL:
Ver original
  1. SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM FROM (SELECT RXFAM1, RXFAM2, RXFAM3, RXFAM4, PSPREC, VMVNNM, ROW_NUMBER() OVER (ORDER BY CASE WHEN @marc = 'ok' THEN VMVNNM END ASC, CASE WHEN @prc = 'desc' THEN PSPREC END DESC, CASE WHEN @prc = 'asc' THEN PSPREC END ASC) AS Recursos FROM Recursos WHERE CPA01 LIKE  [B]([/B]@clave + '%') AS Resultados WHERE Recursos BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)

prueba y comentas :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Última edición por gnzsoloyo; 07/06/2013 a las 16:45
  #5 (permalink)  
Antiguo 06/06/2013, 08:54
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Cita:
Iniciado por Libras Ver Mensaje
creo que te falta un parentesis cerca del like...

"Sintaxis incorrecta cerca de la palabra clave 'AS'."


Libras, ese paréntesis es el que cierra el SELECT.
  #6 (permalink)  
Antiguo 06/06/2013, 09:07
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

si vemos tu query tienes:

Código SQL:
Ver original
  1. SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM
  2. FROM (SELECT RXFAM1, RXFAM2, RXFAM3, RXFAM4, PSPREC, VMVNNM, ROW_NUMBER() OVER (ORDER BY CASE WHEN @marc = 'ok'
  3. THEN VMVNNM END ASC, CASE WHEN @prc = 'desc' THEN PSPREC END DESC, CASE WHEN @prc = 'asc' THEN PSPREC END ASC)
  4. AS Recursos

aqui estas sacando los valores que necesitas y lo pones como una tabla llamada recursos....y le haces un from recursos??

Código SQL:
Ver original
  1. FROM Recursos
  2. WHERE CPA01 LIKE  @clave + '%') AS Resultados WHERE Recursos BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)

si te fijas tienes 2 clausulas from dentro del mismo query......
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #7 (permalink)  
Antiguo 06/06/2013, 09:36
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Cita:
Iniciado por Libras Ver Mensaje

aqui estas sacando los valores que necesitas y lo pones como una tabla llamada recursos....y le haces un from recursos??

si te fijas tienes 2 clausulas from dentro del mismo query......
Con respecto a los FROM esta funcionando bien así en un STORE PROCEDURE tradicional, una se utiliza para la consulta y otro para la paginación.
El problema tal como mencione viene con el string en el sp_executesql.

Use el mismo nombre para el AS que para la tabla, lo cual puede mal entederse. En el SQL a continuacion esta corregido (cambio "Recursos" x "Registros").

Código SQL:
Ver original
  1. SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM FROM (SELECT RXFAM1, RXFAM2, RXFAM3, RXFAM4, PSPREC, VMVNNM, ROW_NUMBER() OVER (ORDER BY CASE WHEN @marc = ''ok'' THEN VMVNNM END ASC, CASE WHEN @prc = ''DESC'' THEN PSPREC END DESC, CASE WHEN @prc = ''ASC'' THEN PSPREC END ASC) AS Registros FROM Recursos WHERE CPA01 LIKE  @clave + ''%'') AS Resultados WHERE Registros BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)
  #8 (permalink)  
Antiguo 06/06/2013, 09:40
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

si hago esto con un query:
Código SQL:
Ver original
  1. SELECT * FROM (SELECT * FROM #temp) AS recursos FROM #temp

que es lo que estas haciendo me marca un error......vuelvo a preguntar estas seguro que el procedure tiene 2 from en un solo query?
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Última edición por gnzsoloyo; 07/06/2013 a las 16:45
  #9 (permalink)  
Antiguo 06/06/2013, 09:47
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Cita:
Iniciado por Libras Ver Mensaje

select * from (select * from #temp) as recursos from #temp
Libras, en esa consulta hay tres FROM y en la que yo puse son solo 2 (uno para traer los registros en base al LIKE de la DB y el otro para la paginación).
  #10 (permalink)  
Antiguo 06/06/2013, 09:54
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

ok mi error :P pero de todos modos yo veo 2 from en tu consulta......
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #11 (permalink)  
Antiguo 06/06/2013, 10:37
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Libras, a modo de ejemplo y extraido de una web -en el SP hay dos FROM-:

Código SQL:
Ver original
  1. CREATE PROCEDURE [dbo].[spPruebaPaginacion]
  2. @Pagina INT,
  3. @RegistrosporPagina INT,
  4.  
  5. AS
  6.  
  7. BEGIN
  8.  
  9. SET NOCOUNT ON;
  10.  
  11. SELECT * FROM (
  12. SELECT ROW_NUMBER()OVER(ORDER BY dbo.PruebaPaginacion.Nombre ASC) AS RowNum, dbo.PruebaPaginacion.Id_Usuario ,
  13. dbo.PruebaPaginacion.Nombre
  14. FROM dbo.PruebaPaginacion
  15. )
  16. AS ResultadoPaginado
  17. WHERE RowNum BETWEEN (@Pagina – 1) * @RegistrosporPagina + 1 AND @Pagina * @RegistrosporPagina
  18.  
  19. END

De hecho justo caí acá, donde vos respondes en una consulta similar que también usa dos FROM:

http://www.forosdelweb.com/f87/consulta-row_number-879121/

Última edición por chueke; 06/06/2013 a las 10:43
  #12 (permalink)  
Antiguo 06/06/2013, 10:55
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

y me das la razon poniendo el codigo de tu procedure :)

Esta es tu cadena:


SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM
FROM
(SELECT RXFAM1, RXFAM2, RXFAM3, RXFAM4, PSPREC, VMVNNM, ROW_NUMBER() OVER (ORDER BY CASE WHEN @marc = ''ok'' THEN VMVNNM END ASC, CASE WHEN @prc = ''DESC'' THEN PSPREC END DESC, CASE WHEN @prc = ''ASC'' THEN PSPREC END ASC
--aqui no hay from
) AS Registros
FROM Recursos
WHERE CPA01 LIKE @clave + ''%'') AS Resultados WHERE Registros BETWEEN 8 * @PageNumber + 1 AND 8 * (@PageNumber + 1)

y este es el codigo del procedure:

SELECT * FROM (
SELECT ROW_NUMBER()Over(ORDER BY dbo.PruebaPaginacion.Nombre ASC) AS RowNum, dbo.PruebaPaginacion.Id_Usuario ,
dbo.PruebaPaginacion.Nombre
FROM dbo.PruebaPaginacion

--aqui si hay un from
)
AS ResultadoPaginado
WHERE RowNum BETWEEN (@Pagina – 1) * @RegistrosporPagina + 1 AND @Pagina * @RegistrosporPagina


Notas una diferencia? Yo si, que esta usando un from dentro de la paginacion ;), a eso me referia con 2 from en un solo query, en el ejemplo que pones tiene 2 from pero en subquerys ;)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #13 (permalink)  
Antiguo 06/06/2013, 11:38
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Cita:
Iniciado por Libras Ver Mensaje
Notas una diferencia?
Haber Libras, tal vez yo me este volviendo loco con esto y no vea la obviedad, jaj.
Estructuralmente ambas sentencias me parecen iguales:

La que uso:

Código SQL:
Ver original
  1. SELECT * FROM (
  2. SELECT *, ROW_NUMBER() OVER
  3. (ORDER BY CASE WHEN @marc = ''ok'' THEN VMVNNM END ASC, CASE WHEN @prc = ''DESC'' THEN PSPREC END DESC, CASE WHEN @prc = ''ASC'' THEN PSPREC END ASC)
  4. AS Registros FROM Recursos WHERE CPA01 LIKE  @clave + ''%'')
  5. AS Resultados WHERE Registros BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)

La que puse de ejemplo:

Código SQL:
Ver original
  1. SELECT * FROM (
  2. SELECT ROW_NUMBER()OVER
  3. (ORDER BY dbo.PruebaPaginacion.Nombre ASC) AS RowNum, dbo.PruebaPaginacion.Id_Usuario ,
  4. dbo.PruebaPaginacion.Nombre FROM dbo.PruebaPaginacion)
  5. AS ResultadoPaginado
  6. WHERE RowNum BETWEEN (@Pagina – 1) * @RegistrosporPagina + 1 AND @Pagina * @RegistrosporPagina


La ubicación de la clausula FROM me parece la misma en ambas.
  #14 (permalink)  
Antiguo 06/06/2013, 14:15
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Order by / Case

prueba con algo como esto:

Código SQL:
Ver original
  1. DECLARE @query Nvarchar(MAX)
  2. SET @query=
  3. 'SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM
  4.    FROM
  5.    (SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM, ROW_NUMBER()
  6.    OVER
  7.    (ORDER BY'  
  8.     -- Orden x marca
  9.     IF @marc='ok'
  10.      SET @query=@query + 'VMVNNM)'
  11.     IF @prc='desc'
  12.      SET @query=query + 'PSPREC)'
  13.     IF @prc='asc'
  14.      SET @query=query + 'PSPREC)'
  15.  
  16.    SET @query=@query + ' AS Recursos
  17.    FROM dbo.Recursos WHERE CPA01 LIKE  ''%'' + @palabra + ''%'')
  18.    AS Resultados
  19.    WHERE Recursos BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)'

saludos!
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #15 (permalink)  
Antiguo 07/06/2013, 14:27
 
Fecha de Ingreso: mayo-2011
Mensajes: 17
Antigüedad: 13 años
Puntos: 2
Respuesta: Order by / Case

Libras, finalmente logre que funcione con la siguiente sentencia:


Código SQL:
Ver original
  1. SELECT * FROM (SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM, ROW_NUMBER()
  2. OVER (ORDER BY CASE WHEN @marc = ''ok'' THEN VMVNNM END ASC, CASE WHEN @prc = ''DESC'' THEN PSPREC END DESC, CASE WHEN @prc = ''ASC'' THEN PSPREC END ASC) AS RowNum FROM Recursos
  3. WHERE
  4. CPA01 LIKE @clave + ''%'')
  5. AS Paginacion WHERE RowNum BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)

Utilizando la misma estructura que funciono (lo que acabo de poner) modifique el LIKE por varios AND en otro SQL, e increiblemente vuelvo a mostrar el mismo error de antes.

Se especificó una expresión no booleana en un contexto donde se esperaba una condición, cerca de 'BETWEE'.

El otro SQL:

Código SQL:
Ver original
  1. SELECT * FROM (SELECT RXFAM1, RXFAM2, RXFAM3, PSPREC, VMVNNM, ROW_NUMBER()
  2. OVER (ORDER BY CASE WHEN @marc = ''ok'' THEN VMVNNM END ASC, CASE WHEN @prc = ''DESC'' THEN PSPREC END DESC, CASE WHEN @prc = ''ASC'' THEN PSPREC END ASC) AS RowNum FROM Recursos
  3. WHERE
  4. (RXFAM1 = COALESCE(NULLIF(@ref1, ''''), RXFAM1)
  5. AND
  6. RXFAM2 = COALESCE(NULLIF(@ref2, ''''), RXFAM2)
  7. AND
  8. RXFAM3 = COALESCE(NULLIF(@ref3, ''''), RXFAM3))
  9. AS Paginacion WHERE RowNum BETWEEN 8 * @PageNumber  + 1 AND 8 * (@PageNumber + 1)

Veo que el problema surge cuando pongo el tercer AND (tengo que poner seis en total). Esto me desorienta por completo, alguna idea?? desde ya, gracias.
  #16 (permalink)  
Antiguo 07/06/2013, 16:46
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Order by / Case

Cita:
alguna idea
Usa un editor con corrector sintáctico. Siempre es una buena opción cuando tienes consultas muy largas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:56.