首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何编写mysql查询,以便从一个表中获得一个记录列表,并将多个其他表的列连在一起

如何编写mysql查询,以便从一个表中获得一个记录列表,并将多个其他表的列连在一起
EN

Stack Overflow用户
提问于 2021-05-02 18:13:24
回答 1查看 304关注 0票数 1

我的问题类似于这个问题:MySQL concatenate values from one table into a record of another

但这并不相同,我想是因为我试图使用来自其他几个表的多个级联列。

这是我的桌子:

代码语言:javascript
运行
复制
CREATE TABLE `Albums` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `userSettingsId` bigint(20) NOT NULL,
  `name` varchar(100) NOT NULL,
  `description` text DEFAULT NULL,
  `isFavorite` tinyint(1) NOT NULL DEFAULT 0,
  `isPublic` tinyint(1) NOT NULL DEFAULT 0,
  `created` datetime NOT NULL DEFAULT current_timestamp(),
  `lastEdited` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`),
  UNIQUE KEY `Albums_UN` (`userSettingsId`,`name`),
  CONSTRAINT `Albums_FK` FOREIGN KEY (`userSettingsId`) REFERENCES `UserSettings` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4;

CREATE TABLE `AlbumsImages` (
  `albumsId` bigint(20) NOT NULL,
  `imagesId` bigint(20) NOT NULL,
  `isCoverImage` tinyint(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (`albumsId`,`imagesId`),
  KEY `AlbumsImages_FK` (`imagesId`),
  CONSTRAINT `AlbumsImages_FK` FOREIGN KEY (`imagesId`) REFERENCES `Images` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `AlbumsImages_FK_1` FOREIGN KEY (`albumsId`) REFERENCES `Albums` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `Collaborators` (
  `albumsId` bigint(20) NOT NULL,
  `access` enum('view','put','edit') NOT NULL DEFAULT 'view',
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`albumsId`,`email`),
  CONSTRAINT `Collaborators_FK_1` FOREIGN KEY (`albumsId`) REFERENCES `Albums` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `Images` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `src` longtext NOT NULL,
  `fileName` varchar(100) NOT NULL,
  `alt` varchar(100) NOT NULL,
  `userSettingsId` bigint(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `Images_UN_FileName_UserSettingsId` (`fileName`,`userSettingsId`),
  KEY `Images_FK` (`userSettingsId`),
  CONSTRAINT `Images_FK` FOREIGN KEY (`userSettingsId`) REFERENCES `UserSettings` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=91 DEFAULT CHARSET=utf8 COMMENT='All images in the application';

CREATE TABLE `UserSettings` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `email` varchar(100) NOT NULL,
  `firstName` varchar(100) NOT NULL,
  `lastName` varchar(100) NOT NULL,
  `password` text NOT NULL,
  `isDarkThemeEnabled` tinyint(1) NOT NULL DEFAULT 1,
  `sessionId` varchar(255) DEFAULT NULL,
  `profilePicture` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UserSettings_Email_UN` (`email`),
  UNIQUE KEY `UserSettings_SessionId_UN` (`sessionId`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT='User Settings and Info'

注意:Collaborators表不使用UserSettings.id的外键,因为协作者不必有帐户。

因此,我想获得所有的专辑和辅助信息,为特定的用户。就像这样:

代码语言:javascript
运行
复制
[
  {
    id: 1,
    name: 'Album Name',
    description: 'Description',
    isFavorite: 0,
    created: '2021-04-26 23:14:05',
    lastEdited: '2021-04-27 19:12:02',
    images: [
      {
        fileName: 'image.jpg',
        alt: 'Image Title',
        src: 'www.image.com/image.jpg',
        isCoverImage: 0,
      }, //...etc
    ],
    collaborators: [
      {
        email: 'someone@example.com',
        firstName: null,
        lastName: null,
        id: null,
        access: 'put',
      },
      {
        email: 'someoneelse@example.com',
        firstName: 'someone',
        lastName: 'else',
        id: 14,
        access: 'view',
      }, //...etc
    ],
  }, //...etc
]

下面是我目前正在处理的查询。

代码语言:javascript
运行
复制
SELECT 
    a.id,
    a.name,
    a.description,
    a.isFavorite,
    a.created,
    a.lastEdited,
    concat('[', group_concat(json_object(
        'fileName', i.fileName,
        'alt', i.alt,
        'src', i.src,
        'isCoverImage', ai.isCoverImage
    )), ']') as images,
    concat('[', group_concat(json_object(
        'email', c.email,
        'firstName', u.firstName,
        'lastName', u.lastName,
        'id', u.id,
        'access', c.access
    )), ']') as collaborators
from Albums a 
    left join AlbumsImages ai
        on a.id=ai.albumsId 
    left join Images i 
        on i.id=ai.imagesId 
    left join Collaborators c 
        on c.albumsId = a.id 
    left join UserSettings u
        on c.email = u.email 
where a.userSettingsId=?
group by id;

它确实有效..。说大也大吧。我得到了所有的相册和他们的所有信息,但是协作者被图片的数量复制,反之亦然。作为目前的一个创可贴,我有一些在查询之后运行的去重复代码,但这显然是很麻烦的,而且不是我想要长期使用的东西。

有什么方法可以解决这个问题来做我想做的事情,还是我是个白痴,因为我一开始就想在一个查询中获取所有这些信息?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-02 18:53:06

所以在合作者和图像之间有一个笛卡儿积。因此,两者都乘以另一个结果的数目。

您可以运行多个查询,然后编写应用程序代码,将结果附加到更大的JSON文档中。

或者您可以使用相关子查询:

代码语言:javascript
运行
复制
SELECT 
    a.id,
    a.name,
    a.description,
    a.isFavorite,
    a.created,
    a.lastEdited,
    concat('[', (
      select group_concat(json_object(
        'fileName', i.fileName,
        'alt', i.alt,
        'src', i.src,
        'isCoverImage', ai.isCoverImage))
      from Images i where i.id=ai.imagesId
    ), ']') as images,
    concat('[', (
      select group_concat(json_object(
        'email', c.email,
        'firstName', u.firstName,
        'lastName', u.lastName,
        'id', u.id,
        'access', c.access))
      from Collaborators c
      left join UserSettings u 
        on c.email = u.email 
      where c.albumsId=a.id
    ), ']') as collaborators
from Albums a 
    left join AlbumsImages ai
        on a.id=ai.albumsId 
where a.userSettingsId=?
group by id;

(未测试)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67359693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档