获取一个返回与类别和子类别相关的项目的查询?

时间:2012-10-11 19:23:13

标签: sql relational-database left-join relation

我想获得一个查询,该查询返回属于某个类别和子类别的所有项目。

以下是设置:

CREATE TABLE [dbo].[CategoriasProductos](
    [IdCategoria] [int] IDENTITY(1,1) NOT NULL,
    [IdGrupo] [int] NULL,
    [Nombre] [varchar](50) NULL,
    [Estado] [varchar](20) NULL,
    [Descripcion] [text] NULL,
    [IdCategoriaPadre] [int] NULL,
    [Nivel] [nchar](10) NULL,
 CONSTRAINT [PK_CategoriasProductos] PRIMARY KEY CLUSTERED 
(
    [IdCategoria] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]



CREATE TABLE [dbo].[Productos](
    [IdProducto] [int] IDENTITY(1,1) NOT NULL,
    [IdGrupo] [int] NULL,
    [IdCategoria] [int] NULL,
    [IdAlmacen] [varchar](50) NULL,
    [Codigo] [varchar](50) NULL,
    [Nombre] [varchar](50) NULL,
    [Descripcion] [varchar](max) NULL,
    [Cantidad] [int] NULL,
    [Imagen] [varchar](max) NULL,
    [StockMin] [int] NULL,
    [StockMax] [int] NULL,
    [Ancho] [varchar](50) NULL,
    [Alto] [varchar](50) NULL,
    [Largo] [varchar](50) NULL,
    [Peso] [varchar](50) NULL,
    [Volumen] [varchar](50) NULL,
    [Color] [varchar](50) NULL,
    [Material] [varchar](50) NULL,
    [Presentacion] [varchar](50) NULL,
    [bitPrecioVentaUnico] [int] NULL,
    [PrecioCompra] [money] NULL,
    [DescuentoCompra] [float] NULL,
    [PrecioVenta] [money] NULL,
    [DescuentoVenta] [float] NULL,
    [Estado] [varchar](20) NULL,
 CONSTRAINT [PK_Productos] PRIMARY KEY CLUSTERED 
(
    [IdProducto] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

现在添加一些数据(至少仅针对类别)

SET IDENTITY_INSERT [dbo].[CategoriasProductos] ON
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (1, 1, N'0')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (2, 1, N'1')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (3, 1, N'1')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (4, 2, N'2')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (5, 2, N'2')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (6, 4, N'3')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (7, 4, N'3')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (10, 5, N'3')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (11, 5, N'3')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (14, 3, N'2')
INSERT [dbo].[CategoriasProductos] ([IdCategoria], [IdCategoriaPadre], [Nivel]) VALUES (15, 3, N'2')
SET IDENTITY_INSERT [dbo].[CategoriasProductos] OFF

(我只插入了我知道将要或者可能需要查询的数据。此外,我的原始数据库中有更多行但插入的数量更少,只是为了不再让它变得复杂)

现在,我暂时尝试了这个问题:

SELECT Productos.Codigo, Productos.Nombre, Productos.Descripcion, A.Nombre AS Categoria
FROM Productos LEFT OUTER JOIN
CategoriasProductos AS A ON Productos.IdCategoria = A.IdCategoria LEFT OUTER JOIN
CategoriasProductos AS B ON B.IdCategoriaPadre = A.IdCategoria LEFT OUTER JOIN
CategoriasProductos AS C ON C.IdCategoriaPadre = B.IdCategoria LEFT OUTER JOIN
CategoriasProductos AS D ON D.IdCategoriaPadre = C.IdCategoria
WHERE (A.IdCategoria = 1)

还有我如何构建查询的图片: http://imageshack.us/a/img841/7029/pruebau.jpg

现在......在查询中,它声明如果A.IdCategoria = 1,(在这种情况下),它应该显示其IdCategoria等于1的所有产品或等于以某种方式链接到IdCategoria 1的另一个值(在分类表中。)

另一个例子可能是我改为键入WHERE B.IdCategoria = 2 ... 然后它应该只显示IdCategoria为2,4,5,6,7,10或11的产品。

我尝试了这个查询但它没有用。也许我没有以正确的方式使用联接......

我想知道是否有人可以告诉我这里我做错了什么,或者我必须添加到查询中以使其正常工作......

我希望你能帮助我 提前致谢

1 个答案:

答案 0 :(得分:1)

LEFT OUTER JOIN不会将额外行引入结果集。它允许您引入额外的列

您拥有的是分层类别。 SO和DBA.SE上有很多关于如何处理层次类别的问题。 SQL在处理层次结构方面不是很好,所以人们经常使用像visitation numbers这样的技巧(另请参阅Nested Sets)。我已多次使用这种技术取得了巨大的成功。

SO上有一个wiki,提供了很多关于人们用来处理分层数据的许多其他方法的文章链接。请记住,每个都涉及某种形式的妥协。您只需选择在您的情况下权衡最有利的那一个。