[SQL] MySQL의 계층 적 재귀 쿼리 만드는 방법
SQLMySQL의 계층 적 재귀 쿼리 만드는 방법
나는 다음과 MySQL의 테이블을 가지고 :
id | name | parent_id
19 | category1 | 0
20 | category2 | 19
21 | category3 | 20
22 | category4 | 21
......
지금, 나는 단순히 ID를 제공하는 단일 MySQL의 쿼리 갖고 싶어 [인스턴스 말에 대한 '를 ID = 19'] 나는 모든 자식 ID를 얻어야한다 [즉, 결과 ....] IDS '20, 21, 22을 가져야 또한, 아이들의 계층 구조가 다를 수 있습니다 알려져 있지 않다 ....
또한, 나는 이미 ..... for 루프를 사용하여 솔루션을 나에게 하나의 MySQL의 쿼리 가능한 경우를 사용하여 동일한을 달성하는 방법을 알려주세요.
해결법
-
==============================
1.MySQL을위한 8 + : 구문 재귀를 사용합니다. MySQL의 5.x의 경우 : 사용 인라인 변수, 경로 ID를, 또는 자체 조인.
MySQL을위한 8 + : 구문 재귀를 사용합니다. MySQL의 5.x의 경우 : 사용 인라인 변수, 경로 ID를, 또는 자체 조인.
with recursive cte (id, name, parent_id) as ( select id, name, parent_id from products where parent_id = 19 union all select p.id, p.name, p.parent_id from products p inner join cte on p.parent_id = cte.id ) select * from cte;
PARENT_ID = 19에 지정된 값은 당신의 모든 자손을 선택하려는 부모의 ID로 설정해야합니다.
MySQL의 버전 공통 테이블 표현식 (버전 5.7까지), 다음 쿼리와이를 달성 할 지원하지 않는 :
select id, name, parent_id from (select * from products order by parent_id, id) products_sorted, (select @pv := '19') initialisation where find_in_set(parent_id, @pv) and length(@pv := concat(@pv, ',', id))
여기에 바이올린입니다.
여기서 @pv에 지정된 값 : = '19'당신의 모든 자손을 선택하려는 부모의 ID로 설정해야합니다.
부모가 여러 자식이 경우에도 작동합니다. 그러나, 그렇지 않으면 결과가 완료되지 않습니다, 각 레코드는 조건 PARENT_ID
이 쿼리는 특정 MySQL의 구문을 사용 변수에 할당하고 실행 중에 수정됩니다. 일부 가정은 실행 순서에 대해 만들어집니다 :
모두 모두, 하나에 의존하는 너무 위험 이러한 가정을 찾을 수 있습니다. 문서는 경고 :
그것은 위의 쿼리와 함께 지속적으로 작동 그럼에도 불구하고, 평가 순서는 여전히 조건을 추가 할 때 예를 들어, 변경하거나 더 큰 쿼리에서보기 또는 하위 쿼리로이 쿼리를 사용할 수 있습니다. 그것은 미래 MySQL의 릴리스에서 제거 될 것 "기능"입니다 :
MySQL은 8.0에서, 위에서 언급 한 바와 같이 이후 당신은 구문으로 재귀를 사용해야합니다.
FIND_IN_SET 작업이 반환 된 레코드의 수와 동일한 정도의 크기의 크기에 도달 목록에 확실히, 목록에서 번호를 찾을 수있는 가장 이상적인 방법하지 아니므로 매우 큰 데이터 세트의이 솔루션은, 느린 얻을 수 있습니다 .
재귀 쿼리 (예 : 포스트 그레스 8.4+, SQL 서버 2005 +, DB2, 오라클 11gR2 +, SQLite는 3.8.4+, 파이어 버드 2.1, H2, HyperSQL 2.1 1999 ISO 표준 [RECURSIVE] 구문 : 점점 더 많은 데이터베이스 SQL을 구현합니다. 0+, 테라 데이타, MariaDB 10.2.2+). 그리고 버전 8.0로, 또한 MySQL은 그것을 지원합니다. 사용하는 구문이 답변의 상단을 참조하십시오.
일부 데이터베이스는 오라클, DB2, 인포믹스, CUBRID와 다른 데이터베이스에서 사용할 수있는 CONNECT BY 절과 같은 계층보기 - 업을위한 대안, 비표준 문법을 가지고있다.
MySQL 버전 5.7은 이러한 기능을 제공하지 않습니다. 데이터베이스 엔진이 구문을 제공하거나이하는 일에 마이그레이션 할 수 있습니다 때, 그 갈 수있는 최선의 선택은 분명하다. 그렇지 않다면, 또한 다음과 같은 대안을 고려하십시오.
경로 : 당신이 계층 정보가 포함 된 ID 값을 할당 할 경우 상황이 훨씬 쉬워집니다. 예를 들어, 귀하의 경우이 다음과 같이 수 :
ID | NAME 19 | category1 19/1 | category2 19/1/1 | category3 19/1/1/1 | category4
그런 다음 선택은 다음과 같이 보일 것이다 :
select id, name from products where id like '19/%'
당신이 당신의 계층 구조 트리가 될 수있는 방법을 깊이에 대한 상한을 알고 있다면, 당신은이 같은 표준 SQL 쿼리를 사용할 수 있습니다 :
select p6.parent_id as parent6_id, p5.parent_id as parent5_id, p4.parent_id as parent4_id, p3.parent_id as parent3_id, p2.parent_id as parent2_id, p1.parent_id as parent_id, p1.id as product_id, p1.name from products p1 left join products p2 on p2.id = p1.parent_id left join products p3 on p3.id = p2.parent_id left join products p4 on p4.id = p3.parent_id left join products p5 on p5.id = p4.parent_id left join products p6 on p6.id = p5.parent_id where 19 in (p1.parent_id, p2.parent_id, p3.parent_id, p4.parent_id, p5.parent_id, p6.parent_id) order by 1, 2, 3, 4, 5, 6, 7;
이 바이올린을 참조하십시오
당신의 후손을 검색하려는 부모를 Where 조건 지정합니다. 필요에 따라 더 수준이 쿼리를 확장 할 수 있습니다.
-
==============================
2.MySQL의 계층 적 데이터 관리 블로그에서
MySQL의 계층 적 데이터 관리 블로그에서
테이블 구조
+-------------+----------------------+--------+ | category_id | name | parent | +-------------+----------------------+--------+ | 1 | ELECTRONICS | NULL | | 2 | TELEVISIONS | 1 | | 3 | TUBE | 2 | | 4 | LCD | 2 | | 5 | PLASMA | 2 | | 6 | PORTABLE ELECTRONICS | 1 | | 7 | MP3 PLAYERS | 6 | | 8 | FLASH | 7 | | 9 | CD PLAYERS | 6 | | 10 | 2 WAY RADIOS | 6 | +-------------+----------------------+--------+
질문:
SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4 FROM category AS t1 LEFT JOIN category AS t2 ON t2.parent = t1.category_id LEFT JOIN category AS t3 ON t3.parent = t2.category_id LEFT JOIN category AS t4 ON t4.parent = t3.category_id WHERE t1.name = 'ELECTRONICS';
산출
+-------------+----------------------+--------------+-------+ | lev1 | lev2 | lev3 | lev4 | +-------------+----------------------+--------------+-------+ | ELECTRONICS | TELEVISIONS | TUBE | NULL | | ELECTRONICS | TELEVISIONS | LCD | NULL | | ELECTRONICS | TELEVISIONS | PLASMA | NULL | | ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH | | ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS | NULL | | ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL | +-------------+----------------------+--------------+-------+
한 번에 또는 다른에서 대부분의 사용자는 SQL 데이터베이스에서 계층 적 데이터 처리 및 의심의 여지가 계층 적 데이터의 관리는 관계형 데이터베이스를위한 것입니다 무엇 아니라는 것을 배운 적이있다. 관계형 데이터베이스의 테이블 (XML과 같은) 계층이 아니라 단순히 단순 목록입니다. 계층 적 데이터는 자연적으로 관계형 데이터베이스 테이블에 표시되지 않은 부모 - 자식 관계가 있습니다. 자세히보기
자세한 내용은 블로그를 참조하십시오.
편집하다:
select @pv:=category_id as category_id, name, parent from category join (select @pv:=19)tmp where parent=@pv
산출:
category_id name parent 19 category1 0 20 category2 19 21 category3 20 22 category4 21
참조 : 어떻게 MySQL의에서 재귀 SELECT 쿼리를 할까?
-
==============================
3.다음을 시도해보십시오
다음을 시도해보십시오
표 정의 :
DROP TABLE IF EXISTS category; CREATE TABLE category ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20), parent_id INT, CONSTRAINT fk_category_parent FOREIGN KEY (parent_id) REFERENCES category (id) ) engine=innodb;
실험 행 :
INSERT INTO category VALUES (19, 'category1', NULL), (20, 'category2', 19), (21, 'category3', 20), (22, 'category4', 21), (23, 'categoryA', 19), (24, 'categoryB', 23), (25, 'categoryC', 23), (26, 'categoryD', 24);
저장 프로 시저를 재귀 :
DROP PROCEDURE IF EXISTS getpath; DELIMITER $$ CREATE PROCEDURE getpath(IN cat_id INT, OUT path TEXT) BEGIN DECLARE catname VARCHAR(20); DECLARE temppath TEXT; DECLARE tempparent INT; SET max_sp_recursion_depth = 255; SELECT name, parent_id FROM category WHERE id=cat_id INTO catname, tempparent; IF tempparent IS NULL THEN SET path = catname; ELSE CALL getpath(tempparent, temppath); SET path = CONCAT(temppath, '/', catname); END IF; END$$ DELIMITER ;
스토어드 프로 시저의 기능 래퍼 :
DROP FUNCTION IF EXISTS getpath; DELIMITER $$ CREATE FUNCTION getpath(cat_id INT) RETURNS TEXT DETERMINISTIC BEGIN DECLARE res TEXT; CALL getpath(cat_id, res); RETURN res; END$$ DELIMITER ;
선택 예 :
SELECT id, name, getpath(id) AS path FROM category;
산출:
+----+-----------+-----------------------------------------+ | id | name | path | +----+-----------+-----------------------------------------+ | 19 | category1 | category1 | | 20 | category2 | category1/category2 | | 21 | category3 | category1/category2/category3 | | 22 | category4 | category1/category2/category3/category4 | | 23 | categoryA | category1/categoryA | | 24 | categoryB | category1/categoryA/categoryB | | 25 | categoryC | category1/categoryA/categoryC | | 26 | categoryD | category1/categoryA/categoryB/categoryD | +----+-----------+-----------------------------------------+
특정 경로 행을 필터링 :
SELECT id, name, getpath(id) AS path FROM category HAVING path LIKE 'category1/category2%';
산출:
+----+-----------+-----------------------------------------+ | id | name | path | +----+-----------+-----------------------------------------+ | 20 | category2 | category1/category2 | | 21 | category3 | category1/category2/category3 | | 22 | category4 | category1/category2/category3/category4 | +----+-----------+-----------------------------------------+
-
==============================
4.나는이 함께 왔어요 가장 좋은 방법
나는이 함께 왔어요 가장 좋은 방법
리니지 접근 DESCR. 예를 들어, 어디든지 찾아 낼 수있다 이곳까지 또는 여기에. 나를 enspired 것입니다 - 함수를 사용합니다.
결국 - 더 - 또는 - 덜 상대적으로 빠르고, 간단, 간단한 솔루션을 얻었다.
기능의 몸
-- -------------------------------------------------------------------------------- -- Routine DDL -- Note: comments before and after the routine body will not be stored by the server -- -------------------------------------------------------------------------------- DELIMITER $$ CREATE DEFINER=`root`@`localhost` FUNCTION `get_lineage`(the_id INT) RETURNS text CHARSET utf8 READS SQL DATA BEGIN DECLARE v_rec INT DEFAULT 0; DECLARE done INT DEFAULT FALSE; DECLARE v_res text DEFAULT ''; DECLARE v_papa int; DECLARE v_papa_papa int DEFAULT -1; DECLARE csr CURSOR FOR select _id,parent_id -- @n:=@n+1 as rownum,T1.* from (SELECT @r AS _id, (SELECT @r := table_parent_id FROM table WHERE table_id = _id) AS parent_id, @l := @l + 1 AS lvl FROM (SELECT @r := the_id, @l := 0,@n:=0) vars, table m WHERE @r <> 0 ) T1 where T1.parent_id is not null ORDER BY T1.lvl DESC; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; open csr; read_loop: LOOP fetch csr into v_papa,v_papa_papa; SET v_rec = v_rec+1; IF done THEN LEAVE read_loop; END IF; -- add first IF v_rec = 1 THEN SET v_res = v_papa_papa; END IF; SET v_res = CONCAT(v_res,'-',v_papa); END LOOP; close csr; return v_res; END
그리고 당신 단지
select get_lineage(the_id)
그것은 누군가가 도움이되기를 바랍니다 :)
-
==============================
5.여기에 또 다른 quetion에 대해 같은 일을했다
여기에 또 다른 quetion에 대해 같은 일을했다
재귀 선택 MYSQL은 여러 수준의 모든 자식을 얻을
쿼리는 다음과 같습니다
SELECT GROUP_CONCAT(lv SEPARATOR ',') FROM ( SELECT @pv:=( SELECT GROUP_CONCAT(id SEPARATOR ',') FROM table WHERE parent_id IN (@pv) ) AS lv FROM table JOIN (SELECT @pv:=1)tmp WHERE parent_id IN (@pv) ) a;
-
==============================
6.당신이 빠른 읽기 속도를 필요로하는 경우, 최선의 선택은 폐쇄 테이블을 사용하는 것입니다. 클로저의 표는 각 상위 / 하위 쌍에 대한 행을 포함합니다. 귀하의 예제에서 그래서, 폐쇄 테이블과 같을 것이다
당신이 빠른 읽기 속도를 필요로하는 경우, 최선의 선택은 폐쇄 테이블을 사용하는 것입니다. 클로저의 표는 각 상위 / 하위 쌍에 대한 행을 포함합니다. 귀하의 예제에서 그래서, 폐쇄 테이블과 같을 것이다
ancestor | descendant | depth 0 | 0 | 0 0 | 19 | 1 0 | 20 | 2 0 | 21 | 3 0 | 22 | 4 19 | 19 | 0 19 | 20 | 1 19 | 21 | 3 19 | 22 | 4 20 | 20 | 0 20 | 21 | 1 20 | 22 | 2 21 | 21 | 0 21 | 22 | 1 22 | 22 | 0
이 테이블이 있으면, 계층 적 쿼리는 매우 쉽고 빠르게된다. 카테고리 (20)의 모든 자손을 얻으려면 :
SELECT cat.* FROM categories_closure AS cl INNER JOIN categories AS cat ON cat.id = cl.descendant WHERE cl.ancestor = 20 AND cl.depth > 0
물론,이 같은 비정규 데이터를 사용할 때마다 큰 단점이있다. 당신은 당신의 카테고리 테이블과 함께 폐쇄 테이블을 유지해야합니다. 가장 좋은 방법은 사용 트리거에 아마이지만, 제대로 폐쇄 테이블에 삽입 / 업데이트 / 삭제를 추적 다소 복잡하다. 아무것도, 당신은 당신의 요구 사항을보고 당신을 위해 무엇이 최선인지 방법을 결정해야합니다.
편집 : 관계형 데이터베이스에서 계층 적 데이터를 저장하는 옵션은 무엇 질문을 참조하십시오? 더 많은 옵션을합니다. 다른 상황에 대해 서로 다른 최적의 솔루션이 있습니다.
-
==============================
7.목록 아이에게 간단한 쿼리는 첫 번째 재귀입니다 :
목록 아이에게 간단한 쿼리는 첫 번째 재귀입니다 :
select @pv:=id as id, name, parent_id from products join (select @pv:=19)tmp where parent_id=@pv
결과:
id name parent_id 20 category2 19 21 category3 20 22 category4 21 26 category24 22
... 왼쪽과 조인
select @pv:=p1.id as id , p2.name as parent_name , p1.name name , p1.parent_id from products p1 join (select @pv:=19)tmp left join products p2 on p2.id=p1.parent_id -- optional join to get parent name where p1.parent_id=@pv
@tincot의 솔루션은 모든 어린이를 나열합니다 :
select id, name, parent_id from (select * from products order by parent_id, id) products_sorted, (select @pv := '19') initialisation where find_in_set(parent_id, @pv) > 0 and @pv := concat(@pv, ',', id)
온라인는 SQL 바이올린과 그것을 테스트하고 모든 결과를 참조하십시오.
http://sqlfiddle.com/#!9/a318e3/4/0
-
==============================
8.당신은 재귀 쿼리 (성능에 YMMV)로 아주 쉽게 다른 데이터베이스에서 이런 식으로 할 수 있습니다.
당신은 재귀 쿼리 (성능에 YMMV)로 아주 쉽게 다른 데이터베이스에서 이런 식으로 할 수 있습니다.
이를 수행하는 다른 방법은 데이터의 두 개의 여분의 비트, 좌측 및 우측의 값을 저장하는 것이다. 왼쪽과 오른쪽 값은 당신이 표현하고있는 트리 구조의 예약 주문 탐색에서 파생됩니다.
이 수정 된 예약 주문 트리 순회로 알고 있고 한 번에 모든 부모 값을 얻기 위해 간단한 쿼리를 실행할 수 있습니다. 또한 이름이 "중첩 된 세트"로 간다.
-
==============================
9.그냥 MySQL의에서 자기 관계 테이블의 메이크업 트리에 대한 BlueM / 트리 PHP 클래스를 사용합니다.
그냥 MySQL의에서 자기 관계 테이블의 메이크업 트리에 대한 BlueM / 트리 PHP 클래스를 사용합니다.
여기 BlueM / 트리를 사용하는 예는 다음과 같습니다
<?php require '/path/to/vendor/autoload.php'; $db = new PDO(...); // Set up your database connection $stm = $db->query('SELECT id, parent, title FROM tablename ORDER BY title'); $records = $stm->fetchAll(PDO::FETCH_ASSOC); $tree = new BlueM\Tree($records); ...
-
==============================
10.당신을 위해 작동하는지 그것 조금 까다로운 하나,이를 확인
당신을 위해 작동하는지 그것 조금 까다로운 하나,이를 확인
select a.id,if(a.parent = 0,@varw:=concat(a.id,','),@varw:=concat(a.id,',',@varw)) as list from (select * from recursivejoin order by if(parent=0,id,parent) asc) a left join recursivejoin b on (a.id = b.parent),(select @varw:='') as c having list like '%19,%';
SQL 바이올린 링크 http://www.sqlfiddle.com/#!2/e3cdf/2
적절하게 필드와 테이블 이름으로 교체합니다.
-
==============================
11.
이 범주 테이블입니다.
SELECT id, NAME, parent_category FROM (SELECT * FROM category ORDER BY parent_category, id) products_sorted, (SELECT @pv := '2') initialisation WHERE FIND_IN_SET(parent_category, @pv) > 0 AND @pv := CONCAT(@pv, ',', id)
산출::
-
==============================
12.A는 (갱신 삽입, 삭제) 쉽게 항목을 허용 대답하지만 큰 계층 구조 쿼리에 대한 다른 저비용의 두 번째 대안 유사한 비트 및 있지만 뭔가는 각 항목에 대한 지속적인 경로 열을 추가 할, 여기 것이라고 언급되지.
A는 (갱신 삽입, 삭제) 쉽게 항목을 허용 대답하지만 큰 계층 구조 쿼리에 대한 다른 저비용의 두 번째 대안 유사한 비트 및 있지만 뭔가는 각 항목에 대한 지속적인 경로 열을 추가 할, 여기 것이라고 언급되지.
일부 같은 :
id | name | path 19 | category1 | /19 20 | category2 | /19/20 21 | category3 | /19/20/21 22 | category4 | /19/20/21/22
예:
-- get children of category3: SELECT * FROM my_table WHERE path LIKE '/19/20/21%' -- Reparent an item: UPDATE my_table SET path = REPLACE(path, '/19/20', '/15/16') WHERE path LIKE '/19/20/%'
대신 실제 숫자 경로 ID를 인코딩 base36를 사용하여 경로 경로 길이 및 ORDER 최적화
// base10 => base36 '1' => '1', '10' => 'A', '100' => '2S', '1000' => 'RS', '10000' => '7PS', '100000' => '255S', '1000000' => 'LFLS', '1000000000' => 'GJDGXS', '1000000000000' => 'CRE66I9S'
https://en.wikipedia.org/wiki/Base36
상기 인코딩 된 ID에 고정 길이 패딩을 사용하여도 슬래시 '/'구분자를 억제
자세한 최적화 설명 여기 : https://bojanz.wordpress.com/2014/04/25/storing-hierarchical-data-materialized-path/
ALL
분할 경로에 함수 또는 프로 시저를 구축하는 것은 하나 개의 항목의 조상을 검색하기위한
-
==============================
13.나를 위해이 작품이 너무 당신을 위해 작동 바랍니다. 그것은 어떤 특정 메뉴 당신에게 아이에 대한 기록 세트 루트를 제공 할 것입니다. 당신의 요구 사항에 따라 필드 이름을 변경합니다.
나를 위해이 작품이 너무 당신을 위해 작동 바랍니다. 그것은 어떤 특정 메뉴 당신에게 아이에 대한 기록 세트 루트를 제공 할 것입니다. 당신의 요구 사항에 따라 필드 이름을 변경합니다.
SET @id:= '22'; SELECT Menu_Name, (@id:=Sub_Menu_ID ) as Sub_Menu_ID, Menu_ID FROM ( SELECT Menu_ID, Menu_Name, Sub_Menu_ID FROM menu ORDER BY Sub_Menu_ID DESC ) AS aux_table WHERE Menu_ID = @id ORDER BY Sub_Menu_ID;
-
==============================
14.나는 더 쉽게 발견
나는 더 쉽게 발견
1) 항목이 다른 하나의 상위 계층에 어디 있는지 확인하는 함수를 만듭니다. 이런 식으로 뭔가 (내가 기능을 쓰기 DO WHILE으로하지 않습니다)
is_related(id, parent_id);
귀하의 예제에서
is_related(21, 19) == 1; is_related(20, 19) == 1; is_related(21, 18) == 0;
2) 사용이 뭔가를 서브 - 선택 :
select ... from table t join table pt on pt.id in (select i.id from table i where is_related(t.id,i.id));
-
==============================
15.나는 당신을 위해 쿼리를 만들었습니다. 이렇게하면 단일 쿼리와 재귀 카테고리를 줄 것이다 :
나는 당신을 위해 쿼리를 만들었습니다. 이렇게하면 단일 쿼리와 재귀 카테고리를 줄 것이다 :
SELECT id,NAME,'' AS subName,'' AS subsubName,'' AS subsubsubName FROM Table1 WHERE prent is NULL UNION SELECT b.id,a.name,b.name AS subName,'' AS subsubName,'' AS subsubsubName FROM Table1 AS a LEFT JOIN Table1 AS b ON b.prent=a.id WHERE a.prent is NULL AND b.name IS NOT NULL UNION SELECT c.id,a.name,b.name AS subName,c.name AS subsubName,'' AS subsubsubName FROM Table1 AS a LEFT JOIN Table1 AS b ON b.prent=a.id LEFT JOIN Table1 AS c ON c.prent=b.id WHERE a.prent is NULL AND c.name IS NOT NULL UNION SELECT d.id,a.name,b.name AS subName,c.name AS subsubName,d.name AS subsubsubName FROM Table1 AS a LEFT JOIN Table1 AS b ON b.prent=a.id LEFT JOIN Table1 AS c ON c.prent=b.id LEFT JOIN Table1 AS d ON d.prent=c.id WHERE a.prent is NULL AND d.name IS NOT NULL ORDER BY NAME,subName,subsubName,subsubsubName
여기에 바이올린입니다.
from https://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 열에 대해 최대 값을 갖는 행을 페치 (0) | 2020.03.05 |
---|---|
[SQL] 내가 항목 X에 액세스 할 수 있도록 어떻게 문자열을 분할합니까? (0) | 2020.03.05 |
[SQL] 는 SQL IN 절을 매개 변수화 (0) | 2020.03.04 |
[SQL] SQL 서버 동적 PIVOT 쿼리? (0) | 2020.03.04 |
[SQL] 어떻게 SQL 서버에서 하나의 텍스트 문자열에 여러 행의 텍스트를 연결하는? (0) | 2020.03.04 |