sourcetip

항목 또는 하위 항목이 태그와 일치하는 경우 항목 선택

fileupload 2023. 9. 5. 20:42
반응형

항목 또는 하위 항목이 태그와 일치하는 경우 항목 선택

목록 항목을 만든 사용자 목록을 선택하려고 합니다.

항목을 나열하는 상위 항목과 나열하는 하위 항목이 있을 수 있습니다.

특정 태그와 일치하는 결과만 표시하거나 자녀가 태그와 일치하는 경우에만 표시해야 합니다.

나는 단순화된 재현 가능한 예를 만들었고 다음과 같은 이유로 쿼리를 약간 변경해야 했습니다.only_full_group_by.

이것은 현재 ID 3(tag-c)의 태그와 일치하는 결과를 보여주기 위한 제 쿼리입니다.

이 쿼리는 일치하는 항목과 게시된 하위 항목의 일부 태그를 표시할 수 없습니다.저는 또한 너무 많이 만지작거려서 현금 자동 인출기가 어린이 항목을 결과로 표시하는 것은 잘못된 것입니다.

CREATE TABLE IF NOT EXISTS `listings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `branchid` int(11) NOT NULL,
  `title` text NOT NULL,
  `published` tinyint(1) NOT NULL DEFAULT '0',
  `uid` int(11) NOT NULL,
  `vid` int(11) NOT NULL,  
  PRIMARY KEY (`id`)
);

INSERT IGNORE INTO `listings` VALUES 
(1, 0, 'Listing',1,1,1),
(2, 0, 'Listing',1,1,1),
(3, 0, 'Listing',1,2,2),
(4, 2, 'Listing B - Child',1,1,1),
(5, 2, 'Listing B - Child',1,1,1),
(6, 3, 'Listing C - Child',1,2,2),
(9, 3, 'Listing C - Child',0,2,2),
(7, 0, 'Listing',1,3,3),
(8, 7, 'Listing D - Child',1,3,3);


CREATE TABLE IF NOT EXISTS `listing_map` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `listing_id` int(11) NOT NULL,
  `tagid` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT IGNORE INTO `listing_map` VALUES 
(600,1,1),
(610,1,2),
(632,2,1),
(650,2,3),
(652,2,4),
(653,3,6),
(654,3,2),
(655,5,1),
(605,5,6),
(590,5,4),
(638,6,2),
(601,6,3),
(611,8,5),
(612,9,1);

CREATE TABLE IF NOT EXISTS `listing_tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
   `title` text NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT IGNORE INTO `listing_tags` VALUES 
(1, 'tag-a'),
(2, 'tag-b'),
(3, 'tag-c'),
(4, 'tag-d'),
(5, 'tag-e'),
(6, 'tag-f');

CREATE TABLE IF NOT EXISTS `vendors` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
   `uid` int(11) NOT NULL,
   `title` text NOT NULL,
   `default` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

INSERT IGNORE INTO `vendors` VALUES 
(1, 1, 'vendor A', 1),
(2, 2, 'vendor B', 0),
(3, 3, 'vendor C', 1),
(4, 4, 'vendor D', 1);

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` text NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT IGNORE INTO `users` VALUES 
(1, 'user A'),
(2, 'user B'),
(3, 'user C'),
(4, 'user D');

https://www.db-fiddle.com/f/pMJvDPNqVRhcEhD4U4r3f7/19

branchid가 0이면 상위 항목입니다.branchid가 숫자인 경우 branchid 부모 항목의 자식입니다.

몇 가지 중요한 조건이 있습니다.

  1. 한 번에 하나의 태그만 검색됩니다.따라서 여러 태그를 일치시킬 필요가 없습니다.
  2. 결과는 태그와 일치하지 않더라도 상위 항목만 표시해야 하지만 하위 항목은 표시해야 합니다.
  3. 결과에는 상위 항목과 하위 항목(존재하는 경우)에 포함된 모든 태그가 표시됩니다.저는 GROUP_CONCAT를 통해 그것을 시도해 왔습니다.
  4. 공개된 부모와 자녀의 상태를 고려해야 합니다.
  5. 한 공급업체에 한 명의 사용자가 할당됨
  6. 목록이 할당되지 않은 공급업체는 공급업체 대신 사용자 제목이 포함된 기본 결과를 얻어야 합니다.
  7. 태그를 검색하면 기본 공급업체에서 더 이상 결과를 얻을 수 없습니다.따라서 "벤더 B"는 아무것도 검색되지 않으면 결과를 얻습니다.

그냥 설명일 뿐입니다.

Listing A
- user 1, vendor 1
- no childs 
- tags: tag-a, tag-b

Listing B
- user 1, vendor 2
- two childs 
- tags: tag-a, tag-c, tag-d, tag-f

Listing C
- user 2, vendor 2
- one child
- tags: tag-f, tag-b, tag-c

Listing D
- user 3, vendor 3
- one child
- tags: tag-e

태그-f와 일치하는 항목 표시:

Listing B (tags: tag-a, tag-c, tag-d, tag-f)
Listing C (tag-f, tag-b, tag-c)

태그-e와 일치하는 항목 표시:

Listing D (tag-e)

모든 항목 표시:

Listing A (tag-a, tag-b)
Listing B (tags: tag-a, tag-c, tag-d, tag-f)
Listing C (tag-f, tag-b, tag-c)
Listing D (tag-e)
Vendor D  (no tags, default entry)

감사해요.

요약하자면, 여기 모든 고아와 관련 태그를 반환하는 쿼리가 있습니다(계층 구조가 한 단계만 깊다고 가정하면)...

제가 고아들을 '0'이 아닌 NULL로 표현하고 있다는 점에 주목하세요. 제가 더 익숙한 것이기 때문입니다. 하지만 원한다면 0으로 다시 변경할 수 있습니다.

SELECT DISTINCT parent.id
              , parent.title listing
              , parent.uid
              , parent.vid
              , t.title tag
           FROM listings parent 
           LEFT
           JOIN listings child 
             ON child.branchid = parent.id
            AND child.published = 1
           JOIN listing_map lt
             ON lt.listing_id IN(parent.id,child.id)
           JOIN listing_tags t
             ON t.id = lt.tagid
          WHERE parent.branchid IS NULL
          ORDER 
             BY parent.id
              , tag;
+----+-----------+-----+-----+-------+
| id | listing   | uid | vid | tag   |
+----+-----------+-----+-----+-------+
|  1 | Listing A |   1 |   1 | tag-a |
|  1 | Listing A |   1 |   1 | tag-b |
|  2 | Listing B |   1 |   1 | tag-a |
|  2 | Listing B |   1 |   1 | tag-c |
|  2 | Listing B |   1 |   1 | tag-d |
|  2 | Listing B |   1 |   1 | tag-f |
|  3 | Listing C |   2 |   2 | tag-b |
|  3 | Listing C |   2 |   2 | tag-c |
|  3 | Listing C |   2 |   2 | tag-f |
|  7 | Listing D |   3 |   3 | tag-e |
+----+-----------+-----+-----+-------+

언급URL : https://stackoverflow.com/questions/65959568/select-items-if-they-or-their-children-match-a-tag

반응형