none
Problema com LEFT JOIN e IN RRS feed

  • Pergunta

  • Pessoal boa tarde!

    Estou com um problema que não consigo colocar para funcionar com o LEFT JOIN ou não estou usar da forma correta. Tenho duas tabelas:
    PRODUTO:

    id_produto  produto
    ----------- --------------------
    1             mouse
    2             teclado
    3             monitor

    PEDIDO:

    id_pedido   data_pedido
    ----------- ----------------------
    1             2012-04-08 00:00:00
    2             2012-04-09 00:00:00
    3             2012-04-04 00:00:00
    4             2012-04-11 00:00:00
    5             2012-04-12 00:00:00
    6             2012-04-09 00:00:00

    Quando executo meu código abaixo:

    WITH relatorio AS
    (
             SELECT produto.id_produto,
                    produto.produto,
                    Count(pedido.id_pedido)  AS TotalPedido,
                    Year(pedido.data_pedido) AS AnoPedido
             FROM   produto
                    LEFT JOIN pedido
                           ON produto.id_produto = pedido.id_produto
             GROUP  BY produto.id_produto,
                       produto.produto,
                       Year(pedido.data_pedido)
             HAVING Year(pedido.data_pedido) IN( 2010, 2011, 2012 )
    )
    SELECT id_produto,
           produto,
           anopedido,
           totalpedido
    FROM   relatorio
    ORDER  BY anopedido;

    Tenho o seguinte resultado:

    id_produto  produto              AnoPedido   TotalPedido
    ----------- -------------------- ----------- -----------
    1             mouse                2012       3
    2             teclado               2012       3

    Os produtos que não tem pedido nos anos solicitados também tem que ser exibidos mesmo na lista desta forma:

    id_produto  produto              AnoPedido   TotalPedido
    ----------- -------------------- ----------- -----------
    1             mouse                2010        0
    2             teclado               2010        0
    3             monitor              2010         0
    1             mouse                2011        0
    2             teclado               2011        0
    3             monitor              2011         0
    1             mouse                2012        3
    2             teclado               2012        3
    3             monitor              2012         0

    Alguém pode me ajudar?

    Script da Base de dados para testar a Query

    USE [Teste]

    GO

    /****** Object:  Table [dbo].[produto] ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    CREATE TABLE [dbo].[produto](

           [id_produto] [int] IDENTITY(1,1) NOT NULL,

           [produto] [nvarchar](20) NULL,

     CONSTRAINT [produto$PrimaryKey] PRIMARY KEY CLUSTERED

    (

           [id_produto] ASC

    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO

    SET IDENTITY_INSERT [dbo].[produto] ON

    INSERT [dbo].[produto] ([id_produto], [produto]) VALUES (1, N'mouse')

    INSERT [dbo].[produto] ([id_produto], [produto]) VALUES (2, N'teclado')

    INSERT [dbo].[produto] ([id_produto], [produto]) VALUES (3, N'monitor')

    SET IDENTITY_INSERT [dbo].[produto] OFF

    /****** Object:  Table [dbo].[pedido] ******/

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    CREATE TABLE [dbo].[pedido](

           [id_pedido] [int] IDENTITY(1,1) NOT NULL,

           [id_produto] [int] NOT NULL,

           [data_pedido] [datetime2](0) NULL,

     CONSTRAINT [pedido$PrimaryKey] PRIMARY KEY CLUSTERED

    (

           [id_pedido] ASC,

           [id_produto] ASC

    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO

    SET IDENTITY_INSERT [dbo].[pedido] ON

    INSERT [dbo].[pedido] ([id_pedido], [id_produto], [data_pedido]) VALUES (1, 1, CAST(0x0000000088350B0000 AS DateTime2))

    INSERT [dbo].[pedido] ([id_pedido], [id_produto], [data_pedido]) VALUES (2, 1, CAST(0x0000000089350B0000 AS DateTime2))

    INSERT [dbo].[pedido] ([id_pedido], [id_produto], [data_pedido]) VALUES (3, 2, CAST(0x0000000084350B0000 AS DateTime2))

    INSERT [dbo].[pedido] ([id_pedido], [id_produto], [data_pedido]) VALUES (4, 2, CAST(0x000000008B350B0000 AS DateTime2))

    INSERT [dbo].[pedido] ([id_pedido], [id_produto], [data_pedido]) VALUES (5, 2, CAST(0x000000008C350B0000 AS DateTime2))

    INSERT [dbo].[pedido] ([id_pedido], [id_produto], [data_pedido]) VALUES (6, 1, CAST(0x0000000089350B0000 AS DateTime2))

    SET IDENTITY_INSERT [dbo].[pedido] OFF

    /****** Object:  ForeignKey [pedido$produtopedido]******/

    ALTER TABLE [dbo].[pedido]  WITH NOCHECK ADD  CONSTRAINT [pedido$produtopedido] FOREIGN KEY([id_produto])

    REFERENCES [dbo].[produto] ([id_produto])

    GO

    ALTER TABLE [dbo].[pedido] CHECK CONSTRAINT [pedido$produtopedido]

    GO



    • Editado LWMN domingo, 10 de junho de 2012 02:18
    sábado, 9 de junho de 2012 21:17

Respostas

  • VMN8,

    O LEFT JOIN não atenderá a sua necessidade da forma como vc usou.

    Tente assim:

    WITH PedidosAno AS 
    (
             SELECT id_produto, 
    				Count(id_pedido) AS TotalPedido,
                    YEAR(data_pedido) AS AnoPedido 
               FROM pedido
              WHERE YEAR(data_pedido) IN ('2010', '2011', '2012') 
              GROUP BY id_produto,
    				   YEAR(data_pedido)
    				   
    ), 
    Relatorio AS 
    (
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2010' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2010' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    
    	UNION ALL 
    
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2011' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2011' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    
    	UNION ALL 
    
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2012' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2012' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    )
    
    SELECT * 
      FROM Relatorio
     ORDER BY AnoPedido


    []'s
    Philipe Souza
    E-mail: Philipe.s.souza@hotmail.com

    • Sugerido como Resposta Carlos Monteiro sábado, 16 de junho de 2012 19:44
    • Marcado como Resposta LWMN domingo, 17 de junho de 2012 16:48
    domingo, 10 de junho de 2012 03:19

Todas as Respostas

  • VMN8,

    O LEFT JOIN não atenderá a sua necessidade da forma como vc usou.

    Tente assim:

    WITH PedidosAno AS 
    (
             SELECT id_produto, 
    				Count(id_pedido) AS TotalPedido,
                    YEAR(data_pedido) AS AnoPedido 
               FROM pedido
              WHERE YEAR(data_pedido) IN ('2010', '2011', '2012') 
              GROUP BY id_produto,
    				   YEAR(data_pedido)
    				   
    ), 
    Relatorio AS 
    (
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2010' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2010' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    
    	UNION ALL 
    
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2011' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2011' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    
    	UNION ALL 
    
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2012' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2012' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    )
    
    SELECT * 
      FROM Relatorio
     ORDER BY AnoPedido


    []'s
    Philipe Souza
    E-mail: Philipe.s.souza@hotmail.com

    • Sugerido como Resposta Carlos Monteiro sábado, 16 de junho de 2012 19:44
    • Marcado como Resposta LWMN domingo, 17 de junho de 2012 16:48
    domingo, 10 de junho de 2012 03:19
  • VMN8,

    O LEFT JOIN não atenderá a sua necessidade da forma como vc usou.

    Tente assim:

    WITH PedidosAno AS 
    (
             SELECT id_produto, 
    				Count(id_pedido) AS TotalPedido,
                    YEAR(data_pedido) AS AnoPedido 
               FROM pedido
              WHERE YEAR(data_pedido) IN ('2010', '2011', '2012') 
              GROUP BY id_produto,
    				   YEAR(data_pedido)
    				   
    ), 
    Relatorio AS 
    (
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2010' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2010' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    
    	UNION ALL 
    
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2011' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2011' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    
    	UNION ALL 
    
    	SELECT pr.id_produto,
    		   pr.produto,
    		   '2012' AS AnoPedido,
    		   CASE pa.AnoPedido
    			 WHEN '2012' THEN  pa.TotalPedido
    			 ELSE 0
    		   END AS TotalPedido
    	  FROM produto pr
    	  LEFT JOIN PedidosAno pa
    		ON pa.id_produto = pr.id_produto
    )
    
    SELECT * 
      FROM Relatorio
     ORDER BY AnoPedido


    []'s
    Philipe Souza
    E-mail: Philipe.s.souza@hotmail.com

    Philipe deu certo, funcionou legal! Obrigado e desculpe pela demora é porque estou quebrando a cabeça com um monte de problemas em consulta.
    domingo, 17 de junho de 2012 16:47