사용 OS : WIN10 PRO
사용프로그램 : MSSQL 2014
---------------------------------------------------------------
무한카테고리를 생성하고 각 언어(한국/중국/일본/영어)별 카테고리별 등록하는데 까지 진행완료 했어요.
--카테고리 데이터
---------------------------------------------
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[category] ON
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (1, N'컴퓨터', 1, 1, 0)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (2, N'가전', 1, 2, 0)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (3, N'스포츠', 1, 3, 0)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (4, N'자동차', 1, 4, 0)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (5, N'여행', 1, 5, 0)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (6, N'노트북', 2, 1, 1)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (8, N'삼성노트북', 3, 1, 6)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (9, N'엘지노트북', 3, 2, 6)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (10, N'S01341
', 4, 1, 8)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (11, N'L01342
', 4, 2, 9)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (12, N'15
', 5, 1, 10)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (13, N'13
', 5, 2, 11)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (14, N' 냉장고
', 1, 2, 2)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (15, N'삼성냉장고
', 3, 1, 14)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (16, N'지펠
', 4, 1, 15)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (17, N'2019년형
', 5, 1, 16)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (18, N'축구
', 2, 1, 3)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (19, N'축구화
', 3, 1, 18)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (20, N'나이키
', 4, 1, 19)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (21, N'아디다스
', 4, 2, 19)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (22, N'성인용
', 5, 1, 20)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (23, N'어린이용
', 5, 2, 21)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (24, N'현대
', 2, 1, 4)
INSERT [dbo].[category] ([CateID], [CateName], [Depth], [DisplaySeq], [ParentID]) VALUES (25, N'가솔린차
', 3, 1, 24)
SET IDENTITY_INSERT [dbo].[category] OFF
go
--category 테이블
------------------------------------------------
CREATE TABLE [dbo].[category](
[cateID] [int] IDENTITY(1,1) NOT NULL,
[CateName] [nchar](100) NOT NULL,
[depth] [int] NOT NULL CONSTRAINT [DF_category_depth] DEFAULT ((1)),
[DisplaySeq] [int] NULL,
[parentID] [int] NOT NULL CONSTRAINT [DF_category_ParentID] DEFAULT ((0)),
[lang] [nvarchar](5) NOT NULL,
CONSTRAINT [PK_category] PRIMARY KEY NONCLUSTERED
(
[cateID] ASC,
[parentID] ASC,
[lang] 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
이 카테고리에 현재까지 5단계까지 있는데
각 단계별 detail 제품을 입력하려 합니다.
이때 제품 테이블은 아래와 같이 설계했어요.
--product 테이블
CREATE TABLE [dbo].[Product](
[prNum] [int] IDENTITY(1,1) NOT NULL,
[prTitle] [varchar](255) NULL,
[prSSN] [nchar](50) NULL,
[prIntro] [varchar](1000) NULL,
[prMainimg] [nvarchar](255) NULL,
[prMainimgOrg] [nvarchar](255) NULL,
[prContent] [ntext] NULL,
[prfile1] [nvarchar](255) NULL,
[prfile2] [nvarchar](255) NULL,
[prfile3] [nvarchar](255) NULL,
[prfile4] [nvarchar](255) NULL,
[prlink1] [nvarchar](255) NULL,
[prlink2] [nvarchar](255) NULL,
[flag] [char](1) NULL CONSTRAINT [DF_Shop_flag] DEFAULT ((0)),
[parentID] [int] NOT NULL,
[cateID] [int] NOT NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[prNum] 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]
GO
질문1) 제품등록 할 때 1,2 단계에서 입력되는것도 있고
5단계까지 가서 입력하는것도 있는데 이 때
어떻게 입력되어야 나중에 제품리스트에서
해당 목록을 검색할 수 있는지요? (cateID만 입력해주면 되는지 아니면 parentID 까지 입력해줘야 하는지 모르겠어요.ㅜㅜ)
질문2) 이렇게 입력되었을때 제품리스트에서 각 단계별로 선택박스 선택하면 해당 목록이 뿌려지게 하는겁니다.
select * from category c join Product p
on c.cateID=p.parentID
where c.lang='kr' and c.depth=1
드롭다운 카테1단계 | 드롭다운 카테2단계 | 드롭다운단 카테3단계 | 드롭다운 카테4단계 | <=선택박스
Comment 5
-
건우아빠
2020.05.23 02:06
-
건우아빠
2020.05.23 02:08
-------------------------------------
-- 구분자를 이용해서 원하는 위치에 값을 가져오는 사용자 함수
-- 오라클 INSTR 흉내...
-------------------------------------
CREATE FUNCTION [dbo].[MssqlINSTR](@OriginalText VARCHAR(8000),@GubunText VARCHAR(100),@Pos INT)
RETURNS VARCHAR(8000)
BEGIN
DECLARE @CleanedText VARCHAR(8000)
DECLARE @ReplaceText VARCHAR(8000)
DECLARE @Minus int ,@I INT ,@TempPOS INT ,@NextTempPOS INT
SET @OriginalText = @GubunText + @OriginalText + @GubunText
SET @ReplaceText = REPLACE(@OriginalText ,@GubunText,'')
SET @Minus = len(@OriginalText) - len(@ReplaceText)
IF @Minus - 1 < @Pos
BEGIN
RETURN ''
END
IF @Pos < 1
BEGIN
RETURN ''
END
SET @TempPOS = 0
SET @I = 0
WHILE @Pos > @I
BEGIN
SET @TempPOS = CHARINDEX(@GubunText, @OriginalText , @TempPOS + 1 )
SET @NextTempPOS = CHARINDEX(@GubunText, @OriginalText , @TempPOS + 1 )
SET @I = @I + 1
END
RETURN SUBSTRING(@OriginalText ,@TempPOS + 1 ,@NextTempPOS - @TempPOS - 1)
END
GO
-
다자녀아빠
2020.05.23 11:52
답변을 달아주셔서 고맙고 감사합니다.^^
쿼리를 보고 이렇게도 되는구나 느꼈습니다.한편으로는 제 지식의 이해력이 아직 감당하기가 어렵네요 ㅠㅠ
곰곰히 생각해보니 그냥 카테고리 4 단계까지 고유번호를 입력해버리면 어떨까 싶어요.카테고리 수량도 몇천개 이내나 보니 그냥 선택된 카테고리별 고유번호를 입력하고
리스트에서 뿌릴 때 그 번호대로 select 해서 뿌리면 되지 않을까 싶네요.
뿌리면 되지 않을까 싶습니다.
-
건우아빠
2020.05.23 12:44
생각하신대로 카테고리 테이블에 각 단계 카테고리(부모카테고리) 를 넣는것도 좋은 방법일것 같습니다.
매번 쿼리로 찾는 방법은 비료율적일수도 있고 데이타 량이 많으면 속도에도 영향을 주니까요.
카테고리 등록 시점에서 부모 카테고리를 등록하시는게 좋을수 있을겁니다.
그래도 기본적으로 재귀쿼리는 익히시는게 좋을듯 합니다.
만약 카테고리를 변경된다면 쿼리를 이용해서 다시 한꺼번에 수정하시는게 편할거구요...
-
다자녀아빠
2020.05.23 14:17
말씀하신대로 재귀쿼리를 능숙하게 할 수 있도록 피나는 노력을 해야 겠네요.
조언을 붙잡고 갑니다.^^
카테고리 테이블에 서브카테고리 존재 유무를 넣는게 원하시는 표를 만들기 쉬울듯 합니다.
서브카테고리가 없는 카테고리만 조회.
displayseq 를 임의로 서브카테고리 존재 유무로 변형 0 없고 1이면 있음.
제품 테이블에는 parentID 는 필요없음...
WITH tree_category AS
(
SELECT cateID ,CateName, depth, DisplaySeq ,parentID
, convert(varchar(1000) , cateID) depth_cateID , convert(varchar(1000) , CateName) depth_CateName
FROM category
WHERE parentID = 0
UNION ALL
SELECT b.cateID ,b.CateName, b.depth, b.DisplaySeq ,b.parentID
, convert(varchar(1000) , convert( varchar(1000),C.depth_cateID) + '/' + convert(varchar(1000) , B.cateID)) depth_cateID
, convert(varchar(1000) , convert( varchar(1000),C.depth_CateName) + '/' + convert(varchar(1000) , B.CateName)) depth_fullname
FROM category B, tree_category C
WHERE B.parentID = C.cateID ) ,
result_base
as(
SELECT cateID , CateName, depth, DisplaySeq , parentID , replace( depth_CateName, ' ','') depth_fullname , depth_cateID
, dbo.MssqlINSTR(replace( depth_CateName, ' ','') , '/',1) depth1_nm
, dbo.MssqlINSTR(replace( depth_CateName, ' ','') , '/',2) depth2_nm
, dbo.MssqlINSTR(replace( depth_CateName, ' ','') , '/',3) depth3_nm
, dbo.MssqlINSTR(replace( depth_CateName, ' ','') , '/',4) depth4_nm
, dbo.MssqlINSTR(replace( depth_CateName, ' ','') , '/',5) depth5_nm
, dbo.MssqlINSTR(replace( depth_cateID, ' ','') , '/',1) depth1_cateID
, dbo.MssqlINSTR(replace( depth_cateID, ' ','') , '/',2) depth2_cateID
, dbo.MssqlINSTR(replace( depth_cateID, ' ','') , '/',3) depth3_cateID
, dbo.MssqlINSTR(replace( depth_cateID, ' ','') , '/',4) depth4_cateID
, dbo.MssqlINSTR(replace( depth_cateID, ' ','') , '/',5) depth5_cateID
FROM tree_category
-- where cateID = 17
-- order by SORT
)
select depth1_nm ,depth2_nm ,depth3_nm ,depth4_nm, depth5_nm -- , *
from result_base
where displayseq = 0
order by convert(int, depth1_cateID) , convert(int, depth2_cateID) , convert(int, depth3_cateID) , convert(int, depth4_cateID) , convert(int, depth5_cateID)