Subselect

Estoy haciendo un store para una Base de datos SQL SERVER2000 y el problema que tengo es que tengo un error de sintaxis y por ese motivo no puedo guardarla. Me dice que tengo un error cerca de la linea 50 (la que esta arriba de donde dice "t1 left join" y lo mismo de la linea 59 que es la que esta arriba del "GO".
Yo lo que quiero hacer con este SP es seleccionar por ejemplo del articulo 1111 el total de todas las ventas en todas las sucursales es decir:

Articulo descripcion precio suc cantvendida canttotalvendida
1111 jean 15 1 25 100
1111 jean 15 2 25 100
1111 jean 15 3 25 100
1111 jean 15 4 25 100
2222 camisa 75 1 25 25

Entonces por eso arme la subconsulta, para que una vez que me trajo la cantidadtotalvendida, yo pueda ordenerlo por el criterio de más vendido.
Te dejo el Store Procedure:
CREATE          proc RankingStock_Nuevo
@FD                      as DATETIME = '2009/08/01',
@FH                      as DATETIME = '2009/08/08',
@SucursalDesde               as int = null,
@SucursalHasta               as int = null,
@Rubro                                as varchar(3) = null,
@Item                    as varchar(6) = null,
@Diferencia        as money = null
AS
while len(@Rubro) < 3
begin
set @Rubro = '0' + @Rubro
end
while len(@Item) < 6
begin
set @Item = '0' + @Item
end
print @FD
print @FH
select Articulo, Descripcion, Nombre, CantidadVendida, CantidadStock, Precio, CantidadTotalVend
(
SELECT     ART.Cod_Art AS Articulo, isnull(ART.descItem, '- Articulo no cargado -') AS Descripcion, SUC.Nombre as Nombre,
SUM(VEN. Cantidad) AS CantidadVendida, max(INV. Cantidad) as CantidadStock, max(VEN. PrecioUnitario) as Precio
FROM         CueVentas VEN LEFT JOIN
(SELECT     descItem, Cod_Art
FROM         vw_Items
GROUP BY descItem, Cod_Art) ART ON VEN.Cod_Art = ART.Cod_Art COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN Inventario INV ON VEN.Cod_Art = INV.CodArt
INNER JOIN Sucursales SUC ON VEN.idSucursal = SUC.idSucursal and INV.idSucursal = SUC.idSucursal
WHERE     CONVERT(varchar, VEN.Fecha, 112) between CONVERT(varchar, isnull(@FD, VEN.Fecha), 112) and CONVERT(varchar, isnull(@FH, VEN.Fecha),112)
AND (VEN.idSucursal BETWEEN ISNULL(@SucursalDesde,VEN.idSucursal)
AND ISNULL(@SucursalHasta,VEN.idSucursal))
and VEN.Cod_Rubro = isnull(@Rubro , VEN.Cod_Rubro)
AND (VEN.Cod_Art = isnull(@Item,VEN.Cod_Art))
--and VEN.Cantidad <> 0
GROUP BY ART.Cod_Art, ART.descItem, SUC.Nombre--, Ven.cantidad--, CAST(cast(year(VEN.Fecha) as varchar) + '-' + cast(month(VEN.Fecha) as varchar) + '-01' AS datetime)
having SUM(ven.cantidad) <>0
)
t1 left join
( select C.Cod_Art, SUM(C.Cantidad) AS CantidadTotalVend
FROM         CueVentas C
WHERE CONVERT(varchar, C.Fecha, 112) between CONVERT(varchar, isnull(@FD, C.Fecha), 112) and CONVERT(varchar, isnull(@FH, C.Fecha),112)
AND (C. IdSucursal BETWEEN ISNULL(@SucursalDesde,C. IdSucursal) AND ISNULL(@SucursalHasta,C. IdSucursal))
and C.Cod_Rubro = isnull(@Rubro , C.Cod_Rubro) AND (C.Cod_Art = isnull(@Item,C.Cod_Art))
GROUP BY C.Cod_Art
)
T2 ON T1.Articulo = T2.Cod_Art
GO
Un abrazo y espero que hayas entendido y espero tu respuesta a la brevedad

1 Respuesta

Respuesta
1
Te voy a dar la solución pero antes recuerda que para desarrollar cualquier cosa es importante el orden, y en los queries el orden es el identado, por eso se te paso lo siguiente:
Te falta la clausula FROM antes de ese "t1 left join" que te marca el SQL,
Puse eso antes de publicar la pregunta y no logre poder probar la query...
Fuera de eso que observe no encuentro más problemas, ademas me es difícil hacerlo sin tener tus tablas ya que así podría darte más ayuda, pero de todas maneras te explico lo que haría:
- Identar las consultas (como si fuera un lenguaje de programación)
- Correr por partes el qry, comenzando desde las subconsultas y luego como un todo.
De esta manera creo que podrás solucionarlo y lamento no poder ayudarte más, ya que como te explique, no veo más errores en tu consulta y no tengo tus tablas para correrlo en mi pc.
Si hay algo más en que pueda ayudarte me avisas.
Mira, en realidad, olvidate de todo lo que te escribí arriba, lo IDEAL seria lograr esto que postie en este link: http://www.todoexpertos.com/mitodoexpertos/ask/2165868/traer-maximo-y-minimo-de-una-suma-sql
si se logra, Seria FANTÁSTICO, esto que postie en una consulta a vos, era una alternativa a lo que te mando el link en esta respuesta.
Saludos. Gracias por tus consejos. Espero tu respuesta pronta para el having de Diferencia..
No pude contestar antes.
Sabes, no encuentro el link que envías, ¿puedes revisarlo?
El link no me sirve, si miras el URL dice "mitodoexpertos" que se refiere a tu usuario y el ask con el numero se refiere a una pregunta que realizaste por ello cuando accedo a tu link me pone la web principal de todo expertos.
Lo que yo necesito es lo siguiente, de la tabla CUEVentas, tengo varios registros con ventas de distintos artículos en diferentes sucursales.
http://img23.imageshack.us/i/cueventas.jpg/
En la consulta RankingStock, yo le mando como veras, diferentes parámetros, en este caso le puse la fecha de hoy. Entonces obtengo los códigos de artículos, descripción, precio y su cantidad vendida y cantidad de stock en cada sucursal.
http://img91.imageshack.us/i/rankingstock.jpg/
Yo necesito poner un Having, que me filtre los artículos que sean muy desparejas sus ventas. Por ejemplo: si en unicenter el articulo 101010 vendo 10 unidades y tiene de stock 190, en abasto vendo 180 y tiene de stock 20, me va a servir más, pasar el stock de Unicenter para el Abasto, ya que en el Abasto, ese articulo se vende mucho más.
Yo lo que tendría que hacer es un Having que agarre el valor MÁXIMO de CantidadVendida de algún articulo en cualquiera de las sucursales y el MÍNIMO de lo mismo.
Articulo sucursal cantvendida
1010 abasto 12
1010 unicenter 20
1010 diaz velez 1
1010 altopalermo 30
El having me tendría que tomar el valor 30 (máximo de cantidad) y 1 (mínimo de cantidad). De esta forma la diferencia es de 29 y si el usuario ingresa en el parámetro diferencia "20", como 29 es mayor, el articulo 1010 va a ingresar en el resultado.
Yo necesito traer en el select siguiente con todos los where que aparecen y que el having filtre por mayor y menor (de los sumarizado que se ve arriba en el select)
Estoy haciendo un store para una Base de datos SQL SERVER2000 y el problema que tengo es que tengo un error de sintaxis y por ese motivo no puedo guardarla. Me dice que tengo un error cerca de la linea 50 (la que esta arriba de donde dice "t1 left join" y lo mismo de la linea 59 que es la que esta arriba del "GO".
Yo lo que quiero hacer con este SP es seleccionar por ejemplo del articulo 1111 el total de todas las ventas en todas las sucursales es decir:
articulo     descripcion      precio  suc    cantvendida     canttotalvendida
1111 jean 15 1 25 100
1111 jean 15 2 25 100
1111 jean 15 3 25 100
1111 jean 15 4 25 100
2222 camisa 75 1 25 25
Entonces por eso arme la subconsulta, para que una vez que me trajo la cantidadtotalvendida, yo pueda ordenerlo por el criterio de más vendido.
Te dejo el Store Procedure:
CREATE          proc RankingStock_Nuevo
@FD                      as DATETIME = '2009/08/01',
@FH                      as DATETIME = '2009/08/08',
@SucursalDesde               as int = null,
@SucursalHasta               as int = null,
@Rubro                                as varchar(3) = null,
@Item                    as varchar(6) = null,
@Diferencia        as money = null
AS
while len(@Rubro) < 3
begin
set @Rubro = '0' + @Rubro
end
while len(@Item) < 6
begin
set @Item = '0' + @Item
end
print @FD
print @FH
select Articulo, Descripcion, Nombre, CantidadVendida, CantidadStock, Precio, CantidadTotalVend
(
SELECT     ART.Cod_Art AS Articulo, isnull(ART.descItem, '- Articulo no cargado -') AS Descripcion, SUC.Nombre as Nombre,
SUM(VEN.Cantidad) AS CantidadVendida, max(INV.Cantidad) as CantidadStock, max(VEN.PrecioUnitario) as Precio
FROM         CueVentas VEN LEFT JOIN
(SELECT     descItem, Cod_Art
FROM         vw_Items
GROUP BY descItem, Cod_Art) ART ON VEN.Cod_Art = ART.Cod_Art COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN Inventario INV ON VEN.Cod_Art = INV.CodArt
INNER JOIN Sucursales SUC ON VEN.idSucursal = SUC.idSucursal and INV.idSucursal = SUC.idSucursal
WHERE     CONVERT(varchar, VEN.Fecha, 112) between CONVERT(varchar, isnull(@FD, VEN.Fecha), 112) and CONVERT(varchar, isnull(@FH, VEN.Fecha),112)
AND (VEN.idSucursal BETWEEN ISNULL(@SucursalDesde,VEN.idSucursal)
AND ISNULL(@SucursalHasta,VEN.idSucursal))
and VEN.Cod_Rubro = isnull(@Rubro , VEN.Cod_Rubro)
AND (VEN.Cod_Art = isnull(@Item,VEN.Cod_Art))
GROUP BY ART.Cod_Art, ART.descItem, SUC.Nombre--, Ven.cantidad--, CAST(cast(year(VEN.Fecha) as varchar) + '-' + cast(month(VEN.Fecha) as varchar) + '-01' AS datetime)
having SUM(ven.cantidad) <>0
LO IDEAL SERIA : HAVING ( MAX(SUM(VEN.CANTIDAD)) - MIN(SUM(VEN.CANTIDAD)) ) >[email protected]
Pero no anda el max y sum a la vez. Saludos.
Sin tus tablas no puedo ayudarte, puedes colgar un script de las tablas involucradas, ademas de algo de data para poder replicarlo, me hes muy pesado ver tu query y tratar de determinar lo que necesitas tal solo viéndolo.
Falta tabla item y querys de insert con data.
http://rapidshare.com/files/267359527/item.sql.html
Lo de datos no se como hacerlo. Si quieres te paso un backup de la bd, pero pesa 200 mb.
Puedes hacer hacer unas clausulas con insert into tabla values ("asda", "asda"a, "was", 132)
De esa manera y poblar con algo de data, o más fácil haz lo siguiente:
Crea una bd nueva: copia las tablas en cuestión a esta bd y pásame el bck, eso sera más ligero.
te pongo la tabla de items completa, backupeada en un TXT
http://rapidshare.com/files/267373367/items.rar.html
y la tabla locales en un .BAK
http://rapidshare.com/files/267376550/BD.rar.html
en el BAK tenes todos los scripts que te envie hoy. Así que descartalos y restaura esto que tienes todo.
Te repito, lo que necesito es que el SP RankingStock, pueda filtrar datos: que en el having, tome la cantidad máxima y mínima de cada articulo, tal cual se imprime cuando lo ejecutas, es decir, si el articulo 1 se vendió 10 unidades en la sucursal Abasto y el articulo 1 se vendió 20 unidades en la sucursa AltoPalermo, y el articulo 1 se vendió 5 unidades en la sucursal Unicenter: la diferencia es 10 (20 de AltoPalermo y 10 de Abasto). Es decir, si el usuario ingreso en el campo Diferencia 8, el articulo 1 debería salir impreso.
Saludos y espero tu respuesta.
Al ejecutar tu consulta con el having max-min no me boto error, pero observe que ese having no tiene sentido porque estas comparando min y max de cantidadvendidad pero estas agregando en el group by a la sucursal, por lo que siempre te leerá todos los datos, hice el siguiente cambio y a mi me funciona, están comentados los agregados pero en resumen tome tu consulta y la hice una subconsulta para luego hacerle el max y min pero sin sucursal:
Declare
    @FD  as DATETIME,
    @FH  as DATETIME,
    @SucursalDesde  as int,
    @SucursalHasta  as int,
    @Rubro  as varchar(3),
    @Item  as varchar(6),
    @Diferencia  as money
set @fd= '01/01/2008'
set @fH= '01/08/2009'
SET @Diferencia= 104
while len(@Rubro) < 3
begin
    set @Rubro = '0' + @Rubro
end
while len(@Item) < 6
begin
    set @Item = '0' + @Item
end
Print @FD
Print @FH
SELECT    Articulo, --agregue este select que te botara los articulos q cumplen el filtro
        Descripción
FROM (
SELECT    ART.Cod_Art AS Articulo,
        isnull(ART.descItem, '- Articulo no cargado -') AS Descripcion, SUC.Nombre,
        SUM(VEN. Cantidad) AS CantidadVendida, max(INV. Cantidad) as CantidadStock,
max(VEN. PrecioUnitario) as Precio
FROM    CueVentas VEN LEFT JOIN
        (
            SELECT    descItem, Cod_Art
            FROM    vw_Items
            GROUP BY descItem, Cod_Art
        ) ART ON VEN.Cod_Art = ART.Cod_Art COLLATE SQL_Latin1_General_CP1_CI_AS
        INNER JOIN Inventario INV ON VEN.Cod_Art = INV.CodArt    
        INNER JOIN Sucursales SUC ON VEN.idSucursal = SUC.idSucursal and INV.idSucursal = SUC.idSucursal
WHERE   CONVERT(varchar, VEN.Fecha, 112) between CONVERT(varchar, isnull(@FD, VEN.Fecha), 112) and CONVERT(varchar, isnull(@FH, VEN.Fecha),112)
        AND (VEN.idSucursal BETWEEN ISNULL(@SucursalDesde,VEN.idSucursal)
        AND ISNULL(@SucursalHasta,VEN.idSucursal))
        and VEN.Cod_Rubro = isnull(@Rubro , VEN.Cod_Rubro)
        AND (VEN.Cod_Art = isnull(@Item,VEN.Cod_Art))     
        AND ART.Cod_Art IS NOT NULL
        AND ART.Cod_Art= '110192'
GROUP BY ART.Cod_Art, ART.descItem, SUC.Nombre--, Ven.cantidad--, CAST(cast(year(VEN.Fecha) as varchar) + '-' + cast(month(VEN.Fecha) as varchar) + '-01' AS datetime)
having SUM(ven.cantidad) <>0 --hasta aca todo bien
)A  --Esto es lo q te comento, recien aca buscara max y min de los productos pero de la consulta que tu creaste reduciendo la busqueda
GROUP BY Articulo, 
        Descripcion
HAVING    MAX(CantidadVendida) - MIN(CantidadVendida) >= @Diferencia
Agradezco tu respuesta, pero aun me esta faltando que se imprima la CantidadVendida, CantidadStock, Nombre (de la sucursal) y Precio. Con eso ya me serviría muchísimo
Espero tu respuesta, gracias.
Disculpa la demora, mucho trabajo.
Ahora, retomando tu caso, tu quieres visualizar todos los datos de los artículos que cumplan con la validación.
Bueno he modificado el qry, revísalo y si tiens dudas me comentas.
Declare
    @FD  as DATETIME,
    @FH  as DATETIME,
    @SucursalDesde  as int,
    @SucursalHasta  as int,
    @Rubro  as varchar(3),
    @Item  as varchar(6),
    @Diferencia  as money
set @fd= '01/01/2008'
set @fH= '01/08/2009'
SET @Diferencia= 104
while len(@Rubro) < 3
begin
    set @Rubro = '0' + @Rubro
end
while len(@Item) < 6
begin
    set @Item = '0' + @Item
end
Print @FD
Print @FH
Declare @Data table
(
    Articulo varchar(100),
    Descripción varchar(100),
    Nombre varchar(100),
cantidadvendida int,
cantidadstock int,
precio decimal(18,2)
)
insert into @data
SELECT    ART.Cod_Art AS Articulo,
        isnull(ART.descItem, '- Articulo no cargado -') AS Descripcion,
        SUC.Nombre,
        SUM(VEN. Cantidad) AS CantidadVendida,
max(INV. Cantidad) as CantidadStock,
max(VEN. PrecioUnitario) as Precio
FROM    CueVentas VEN LEFT JOIN
        (
            SELECT    descItem, Cod_Art
            FROM    vw_Items
            GROUP BY descItem, Cod_Art
        ) ART ON VEN.Cod_Art = ART.Cod_Art COLLATE SQL_Latin1_General_CP1_CI_AS
        INNER JOIN Inventario INV ON VEN.Cod_Art = INV.CodArt    
        INNER JOIN Sucursales SUC ON VEN.idSucursal = SUC.idSucursal and INV.idSucursal = SUC.idSucursal
WHERE   CONVERT(varchar, VEN.Fecha, 112) between CONVERT(varchar, isnull(@FD, VEN.Fecha), 112) and CONVERT(varchar, isnull(@FH, VEN.Fecha),112)
        AND (VEN.idSucursal BETWEEN ISNULL(@SucursalDesde,VEN.idSucursal)
        AND ISNULL(@SucursalHasta,VEN.idSucursal))
        and VEN.Cod_Rubro = isnull(@Rubro , VEN.Cod_Rubro)
        AND (VEN.Cod_Art = isnull(@Item,VEN.Cod_Art))     
        AND ART.Cod_Art IS NOT NULL
        AND ART.Cod_Art= '110192'
GROUP BY ART.Cod_Art, ART.descItem, SUC.Nombre--, Ven.cantidad--, CAST(cast(year(VEN.Fecha) as varchar) + '-' + cast(month(VEN.Fecha) as varchar) + '-01' AS datetime)
having SUM(ven.cantidad) <>0
select    a.*
from    @data a inner join
        (
            SELECT    Articulo,
                    Descripción
            FROM    @data
            GROUP BY Articulo,
                    Descripcion
            HAVING    MAX(CantidadVendida) - MIN(CantidadVendida) >= @Diferencia
        )b on a.Articulo= b.articulo
Fenómeno, ahí anda espectacular. Lo que me faltaría es para guardarlo como Store Procedure, ya que es para utilizar como SP (obviamente que le comento los SET de Fechas y Diferencia y comento lo del where codart) pero no me deja porque arranca con DECLARE y debería empezar con CReate proc NOMBRE
Saludos y gracias nuevamente,.
Bueno eso ya es fácil de hacer, reemplaza el declare por create store procedure nombre:
create store procedure NOMBRE
    @FD  as DATETIME,
    @FH  as DATETIME,
    @SucursalDesde  as int,
    @SucursalHasta  as int,
    @Rubro  as varchar(3),
    @Item  as varchar(6),
    @Diferencia  as money
As
--set @fd= '01/01/2008'
--set @fH= '01/08/2009'
--SET @Diferencia= 104
************************
PD: No te olvides cerrar la pregunta.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas