mysql - 使用包含来自数据透视表的匹配项的虚拟列从标签表中选择所有记录

标签 mysql pivot-table

我正在尝试:

选择所有标签(来自标签表)

有一个名为 selected 的虚拟列

包含一个 bool 值(例如 0 || 1)

定义 tag_id 是否与给定的 image_id 相关联

(Es.image_id = 1)

它在名为 image_tag 的数据透视表中预设的关系数据集

结构和数据:

CREATE TABLE IF NOT EXISTS `images` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `images` (`id`, `title`) VALUES
(1, 'Image 1'),
(2, 'Image 2');

CREATE TABLE IF NOT EXISTS `tags` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `tags_name_unique` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `tags` (`id`, `name`) VALUES
(1, 'Tag A'),
(2, 'Tag B'),
(3, 'Tag C'),
(4, 'Tag D');

/* Pivot table */
CREATE TABLE IF NOT EXISTS `image_tag` (
  `image_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL,
  PRIMARY KEY (`image_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `image_tag` (`image_id`, `tag_id`) VALUES
(1, 1),
(1, 2),
(2, 1),
(2, 3);

SELECT * FROM images;
/*
+----+---------+
| id | title   |
+----+---------+
|  1 | Image 1 |
|  2 | Image 2 |
+----+---------+
*/

SELECT * FROM tags;
/*
+----+-------+
| id | name  |
+----+-------+
|  1 | Tag A |
|  2 | Tag B |
|  3 | Tag C |
|  4 | Tag D |
+----+-------+
*/

SELECT * FROM image_tag;
/*
+----------+--------+
| image_id | tag_id |
+----------+--------+
|        1 |      1 |
|        1 |      2 |
|        2 |      1 |
|        2 |      3 |
+----------+--------+
*/

我正在寻找的结果:

/*
+----+-------+----------+
| id | tag   | selected |
+----+-------+----------+
|  1 | Tag A | 1        |
|  2 | Tag B | 1        |
|  3 | Tag C | 0        |
|  4 | Tag D | 0        |
+----+-------+----------+
*/

感谢您的帮助:)

最佳答案

tagsimage_tags 表之间进行左连接,然后使用检查匹配计数的 CASE 表达式。如果匹配计数为零,则为 selected 列报告零,否则报告 1。

SELECT
    t1.id,
    t1.name AS tag,
    CASE WHEN COUNT(t2.tag_id) = 0 THEN 0 ELSE 1 END AS selected
FROM tags t1
LEFT JOIN image_tag t2
    ON t1.id = t2.tag_id AND
       t2.image_id = 1
GROUP BY
    t1.id,
    t1.name
ORDER BY
    t1.id;

注意:我的原始答案返回与任何图像匹配的标签。从那时起,OP 让我知道要求是标签与特定图像匹配。上面的查询和演示反射(reflect)了这一点,但不是屏幕截图。

enter image description here

Demo

关于mysql - 使用包含来自数据透视表的匹配项的虚拟列从标签表中选择所有记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48181032/

相关文章:

Php 用 str_replace 清理双破折号

Pandas 数据透视表内存错误,大量可用内存

excel - 如何按多列对数据透视表排序?

python - Pandas:使用 groupby 或数据透视表时按顺序排列日期

excel - 以编程方式构建 Excel 数据透视表

mysql在同一过程中使用返回值

sql - 如何在 SQL 查询中获取结果集的字节大小?

mysql - 形成复杂的SQL语句

mysql - 复制表格行并将它们粘贴到同一个表格中

sql - PostgreSQL 9.3 : Pivot table query