Problemas usando UNION, FIRST e ORDER BY
Estou tentando listar 10 produtos mais vendidos junto com os produtos não vendidos.
Segue a estrutura das tabelas:
VENDA
CODIGOVENDA INTEGER NOT NULL
DATA DATE
NOMECLIENTE VARCHAR(40)
TOTAL NUMERIC(15,2)
CODIGOCLIENTE INTEGER
VENDA_ITENS
VALOR DOUBLE PRECISION
QUANTIDADE DOUBLE PRECISION
ICMVENDA NUMERIC(9,2)
CODIGOPRODUTO INTEGER NOT NULL
CODIGOVENDA INTEGER NOT NULL
PRODUTO
CODIGOPRODUTO INTEGER NOT NULL
DESCRICAO VARCHAR(50) NOT NULL
UNIDADE VARCHAR(2)
SALDOFISICO DOUBLE PRECISION
PRECOVENDA VALOR
ICMVENDA PERCENTAGEM
CODIGOTRIBUTARIO VARCHAR(2)
CODIGOEXPORTACAO VARCHAR(20)
Minha intencao é listar os produtos mais vendidos juntamente com os não vendidos. Abaixo a instrução que funciona perfeitamente:
SELECT
P.DESCRICAO,
SUM(I.QUANTIDADE) AS SOMAQUANTIDADE,
SUM(I.VALOR) AS SOMAVALOR
FROM
VENDA_ITENS I, VENDA V
INNER JOIN
PRODUTO P ON (P.CODIGOPRODUTO = I.CODIGOPRODUTO)
WHERE
(I.CODIGOVENDA = V.CODIGOVENDA
AND V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
GROUP BY P.DESCRICAO
UNION ALL
SELECT
DESCRICAO,
0.000 SOMAQUANTIDADE,
0.000 SOMAVALOR
FROM
PRODUTO
WHERE
CODIGOPRODUTO NOT IN
(SELECT DISTINCT I.CODIGOPRODUTO
FROM VENDA_ITENS I, VENDA V
WHERE I.CODIGOVENDA = V.CODIGOVENDA
AND V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
ORDER BY 2 DESCENDING
A partir dai preciso mostrar apenas os 10 itens mais vendidos que estão no primeiro SELECT. Se coloco o FIRST lá em cima ele mostra apenas 10 mas nao necessariamente os mais vendidos. Se coloco um ORDER BY para o SELECT de cima dá erro..
Uso Firebird 1.5.1.4481
Segue a estrutura das tabelas:
VENDA
CODIGOVENDA INTEGER NOT NULL
DATA DATE
NOMECLIENTE VARCHAR(40)
TOTAL NUMERIC(15,2)
CODIGOCLIENTE INTEGER
VENDA_ITENS
VALOR DOUBLE PRECISION
QUANTIDADE DOUBLE PRECISION
ICMVENDA NUMERIC(9,2)
CODIGOPRODUTO INTEGER NOT NULL
CODIGOVENDA INTEGER NOT NULL
PRODUTO
CODIGOPRODUTO INTEGER NOT NULL
DESCRICAO VARCHAR(50) NOT NULL
UNIDADE VARCHAR(2)
SALDOFISICO DOUBLE PRECISION
PRECOVENDA VALOR
ICMVENDA PERCENTAGEM
CODIGOTRIBUTARIO VARCHAR(2)
CODIGOEXPORTACAO VARCHAR(20)
Minha intencao é listar os produtos mais vendidos juntamente com os não vendidos. Abaixo a instrução que funciona perfeitamente:
SELECT
P.DESCRICAO,
SUM(I.QUANTIDADE) AS SOMAQUANTIDADE,
SUM(I.VALOR) AS SOMAVALOR
FROM
VENDA_ITENS I, VENDA V
INNER JOIN
PRODUTO P ON (P.CODIGOPRODUTO = I.CODIGOPRODUTO)
WHERE
(I.CODIGOVENDA = V.CODIGOVENDA
AND V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
GROUP BY P.DESCRICAO
UNION ALL
SELECT
DESCRICAO,
0.000 SOMAQUANTIDADE,
0.000 SOMAVALOR
FROM
PRODUTO
WHERE
CODIGOPRODUTO NOT IN
(SELECT DISTINCT I.CODIGOPRODUTO
FROM VENDA_ITENS I, VENDA V
WHERE I.CODIGOVENDA = V.CODIGOVENDA
AND V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
ORDER BY 2 DESCENDING
A partir dai preciso mostrar apenas os 10 itens mais vendidos que estão no primeiro SELECT. Se coloco o FIRST lá em cima ele mostra apenas 10 mas nao necessariamente os mais vendidos. Se coloco um ORDER BY para o SELECT de cima dá erro..
Uso Firebird 1.5.1.4481
Lhs
Curtidas 0
Respostas
Gandalf.nho
25/10/2004
Sugestão: tente montar uma Stored Procedure, acho que é mais simples e você pode controlar melhor o resultado. Coloque um laço FOR... DO com a primeira SQL com o FIRST e ORDER BY, ponha SUSPEND dentro do laço e repita o processo com a segunda SQL.
GOSTEI 0
Emerson Nascimento
25/10/2004
SELECT FIRST 10 P.DESCRICAO,
        SUM(I.QUANTIDADE) AS SOMAQUANTIDADE,
        SUM(I.VALOR) AS SOMAVALOR
FROM VENDA_ITENS I
INNER JOIN VENDA V ON (V.CODIGOVENDA=I.CODIGOVENDA)
INNER JOIN PRODUTO P ON (P.CODIGOPRODUTO = I.CODIGOPRODUTO)
WHERE (V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
GROUP BY P.CODIGOPRODUTO
ORDER BY 2 DESC
UNION ALL
SELECT DESCRICAO,
          0.000 SOMAQUANTIDADE,
          0.000 SOMAVALOR
FROM PRODUTO
WHERE NOT CODIGOPRODUTO IN
    (SELECT DISTINCT I.CODIGOPRODUTO
      FROM VENDA_ITENS I
      INNER JOIN VENDA V ON (V.CODIGOVENDA = I.CODIGOVENDA)
      WHERE V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
ORDER BY DESCRICAO
        SUM(I.QUANTIDADE) AS SOMAQUANTIDADE,
        SUM(I.VALOR) AS SOMAVALOR
FROM VENDA_ITENS I
INNER JOIN VENDA V ON (V.CODIGOVENDA=I.CODIGOVENDA)
INNER JOIN PRODUTO P ON (P.CODIGOPRODUTO = I.CODIGOPRODUTO)
WHERE (V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
GROUP BY P.CODIGOPRODUTO
ORDER BY 2 DESC
UNION ALL
SELECT DESCRICAO,
          0.000 SOMAQUANTIDADE,
          0.000 SOMAVALOR
FROM PRODUTO
WHERE NOT CODIGOPRODUTO IN
    (SELECT DISTINCT I.CODIGOPRODUTO
      FROM VENDA_ITENS I
      INNER JOIN VENDA V ON (V.CODIGOVENDA = I.CODIGOVENDA)
      WHERE V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
ORDER BY DESCRICAO
GOSTEI 0
Emerson Nascimento
25/10/2004
Desculpe, havia um erro no Group By. O correto seria:
SELECT FIRST 10 P.DESCRICAO,
        SUM(I.QUANTIDADE) AS SOMAQUANTIDADE,
        SUM(I.VALOR) AS SOMAVALOR
FROM VENDA_ITENS I
INNER JOIN VENDA V ON (V.CODIGOVENDA=I.CODIGOVENDA)
INNER JOIN PRODUTO P ON (P.CODIGOPRODUTO = I.CODIGOPRODUTO)
WHERE (V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
GROUP BY P.DESCRICAO
ORDER BY 2 DESC
UNION ALL
SELECT DESCRICAO,
          0.000 SOMAQUANTIDADE,
          0.000 SOMAVALOR
FROM PRODUTO
WHERE NOT CODIGOPRODUTO IN
    (SELECT DISTINCT I.CODIGOPRODUTO
      FROM VENDA_ITENS I
      INNER JOIN VENDA V ON (V.CODIGOVENDA = I.CODIGOVENDA)
      WHERE V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
ORDER BY DESCRICAO
SELECT FIRST 10 P.DESCRICAO,
        SUM(I.QUANTIDADE) AS SOMAQUANTIDADE,
        SUM(I.VALOR) AS SOMAVALOR
FROM VENDA_ITENS I
INNER JOIN VENDA V ON (V.CODIGOVENDA=I.CODIGOVENDA)
INNER JOIN PRODUTO P ON (P.CODIGOPRODUTO = I.CODIGOPRODUTO)
WHERE (V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
GROUP BY P.DESCRICAO
ORDER BY 2 DESC
UNION ALL
SELECT DESCRICAO,
          0.000 SOMAQUANTIDADE,
          0.000 SOMAVALOR
FROM PRODUTO
WHERE NOT CODIGOPRODUTO IN
    (SELECT DISTINCT I.CODIGOPRODUTO
      FROM VENDA_ITENS I
      INNER JOIN VENDA V ON (V.CODIGOVENDA = I.CODIGOVENDA)
      WHERE V.DATA BETWEEN ´10/01/2004´ AND ´10/31/2004´)
ORDER BY DESCRICAO
GOSTEI 0