在select语句中获取计数时遇到问题

时间:2016-04-19 19:29:27

标签: mysql sql select

我有5张表如下:

  • 文件
  • 标记
  • 简档
  • j_file_tags
  • j_profile_tags

因此,文件可以包含标签,配置文件可以访问某些标签。

我整理了两个执行以下操作的查询:

  1. 获取特定配置文件可以访问的文件列表(配置文件必须能够访问文件可能具有的所有标记)
  2. 获取个人资料有权访问的标记列表以及该标记中至少有一个文件。
  3. 查询2需要的是对标记中文件数量的计数。

    这是表格结构和样本数据:

    CREATE TABLE `files` (
    `id`  int(4) NOT NULL AUTO_INCREMENT ,
    `fileName`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
    `empID`  int(4) NOT NULL ,
    PRIMARY KEY (`id`)
    )
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    ROW_FORMAT=Dynamic;
    
    CREATE TABLE `j_file_tags` (
    `id`  int(4) NOT NULL AUTO_INCREMENT ,
    `fileID`  int(4) NULL DEFAULT NULL ,
    `tagID`  int(4) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`)
    )
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    ROW_FORMAT=Dynamic;
    
    CREATE TABLE `j_profile_tags` (
    `id`  int(4) NOT NULL AUTO_INCREMENT ,
    `profileID`  int(4) NULL DEFAULT NULL ,
    `tagID`  int(4) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`)
    )
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    ROW_FORMAT=Dynamic;
    
    CREATE TABLE `profiles` (
    `id`  int(4) NOT NULL AUTO_INCREMENT ,
    `profileName`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
    PRIMARY KEY (`id`)
    )
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    ROW_FORMAT=Dynamic;
    
    CREATE TABLE `tags` (
    `id`  int(4) NOT NULL AUTO_INCREMENT ,
    `tagName`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
    PRIMARY KEY (`id`)
    )
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    ROW_FORMAT=Dynamic;
    
    INSERT INTO `files` VALUES ('1', 'FileOne', '1');
    INSERT INTO `files` VALUES ('2', 'FileTwo', '1');
    INSERT INTO `files` VALUES ('3', 'FileThree', '1');
    INSERT INTO `files` VALUES ('4', 'FileFour', '2');
    INSERT INTO `files` VALUES ('5', 'FileFive', '2');
    INSERT INTO `files` VALUES ('6', 'FileSix', '2');
    INSERT INTO `files` VALUES ('7', 'FileSeven', '2');
    
    INSERT INTO `profiles` VALUES ('1', 'ProfileOne');
    INSERT INTO `profiles` VALUES ('2', 'ProfileTwo');
    INSERT INTO `profiles` VALUES ('3', 'ProfileThree');
    
    INSERT INTO `tags` VALUES ('1', 'TagOne');
    INSERT INTO `tags` VALUES ('2', 'TagTwo');
    INSERT INTO `tags` VALUES ('3', 'TagThree');
    INSERT INTO `tags` VALUES ('4', 'TagFour');
    INSERT INTO `tags` VALUES ('5', 'TagFive');
    
    INSERT INTO `j_file_tags` VALUES ('1', '1', '1');
    INSERT INTO `j_file_tags` VALUES ('2', '1', '3');
    INSERT INTO `j_file_tags` VALUES ('3', '2', '1');
    INSERT INTO `j_file_tags` VALUES ('4', '2', '5');
    INSERT INTO `j_file_tags` VALUES ('5', '3', '1');
    INSERT INTO `j_file_tags` VALUES ('6', '3', '3');
    INSERT INTO `j_file_tags` VALUES ('7', '3', '6');
    INSERT INTO `j_file_tags` VALUES ('8', '2', '3');
    INSERT INTO `j_file_tags` VALUES ('9', '4', '1');
    INSERT INTO `j_file_tags` VALUES ('10', '4', '2');
    INSERT INTO `j_file_tags` VALUES ('11', '5', '1');
    INSERT INTO `j_file_tags` VALUES ('12', '5', '6');
    
    INSERT INTO `j_profile_tags` VALUES ('1', '1', '2');
    INSERT INTO `j_profile_tags` VALUES ('2', '1', '3');
    INSERT INTO `j_profile_tags` VALUES ('3', '1', '4');
    INSERT INTO `j_profile_tags` VALUES ('4', '2', '1');
    INSERT INTO `j_profile_tags` VALUES ('5', '2', '2');
    INSERT INTO `j_profile_tags` VALUES ('6', '2', '3');
    INSERT INTO `j_profile_tags` VALUES ('7', '2', '4');
    INSERT INTO `j_profile_tags` VALUES ('8', '2', '5');
    INSERT INTO `j_profile_tags` VALUES ('9', '1', '1');
    INSERT INTO `j_profile_tags` VALUES ('10', '1', '5');
    

    以下是我的2个查询:

    /* Get list of files: limit by specific employee AND by tags the use has access to  */
    SELECT 
        `files`.`id`,
        `files`.`fileName`,
        `files`.`empID`,
        GROUP_CONCAT(CONCAT(`tags`.`id`)  SEPARATOR ', ') as `FileTags`
    FROM `files`
    LEFT JOIN `j_file_tags` ON `j_file_tags`.`fileID` = `files`.`id`
    LEFT JOIN `tags` ON `tags`.`id` = `j_file_tags`.`tagID`
    WHERE
        `files`.`empID` = 1
        AND
        `j_file_tags`.`tagID` IN (1,2,3,4,5)
    GROUP BY 
        `files`.`id`
    HAVING 
        COUNT(`j_file_tags`.`id`) = (SELECT COUNT(`j_file_tags`.`id`) FROM `j_file_tags` WHERE `j_file_tags`.`fileID` = `files`.`id` );
    
    /* SECOND QUERY where i need help */
    SELECT 
        `tags`.`id`,
        `tags`.`tagName`,
        '1' as `fileCount` /* i need this to be an actual count */
    FROM
        `tags`
    LEFT JOIN `j_file_tags` ON `j_file_tags`.`tagID` = `tags`.`id`
    LEFT JOIN `files` ON `files`.`id` = `j_file_tags`.`fileID`
    LEFT JOIN `j_profile_tags` ON `j_profile_tags`.`tagID` = `tags`.`id`
    WHERE
        `j_profile_tags`.`profileID` = 1
        AND 
        `files`.`empID` = 1
    GROUP BY
        `tags`.`id`;
    /* the fileCount column would need to say for TagOne - 2, for TagThree - 2 and for TagFive - 1 */
    

    在示例数据中,第一个查询返回:

    • | 1 | FileOne | 1 | 1,3,
    • | 2 | FileTwo | 1 | 3,1,5

    第二个查询返回:

    • | 1 | TagOne |应该返回2
    • | 3 | TagThree |应该返回2
    • | 5 | TagFive | |应该返回1

1 个答案:

答案 0 :(得分:0)

答案很简单,你在第一个查询中的HAVING子句会丢掉你的结果,因为真的有3个文件带有标签1和3.我建议将它们全部一起删除或者找出另一种方法来实现它。我在下面重写了您的查询以显示您想要的结果,但这不是一个全部修复。

选择     tagsid,     tagstagName,     count(fileID)为' fileCount' 来自files LEFT JOIN j_file_tags点击j_file_tagsfileID = filesid LEFT JOIN tags点击tagsid = j_file_tagstagID 哪里     filesempID = 1     和     j_file_tagstagID IN(1,2,3,4,5)     和     fileID IN(1,2) 通过...分组     tagsid

相关问题