Mysql复杂查询失败

时间:2016-06-15 07:25:25

标签: mysql

我有两个表,ProfileStatus,用于人类信息。

我已经为Profile表中的每个人存储了一个唯一的TagId,并且我在Status表上存储了多个记录。

SQL Fiddle

CREATE TABLE IF NOT EXISTS `Profile` (
  `tagId` INT(15) NOT NULL,
  `sex` VARCHAR(10) NOT NULL,
  INDEX `sex_idx` (`sex` ASC),
  UNIQUE INDEX `tagId_UNIQUE` (`tagId` ASC),
  PRIMARY KEY (`tagId`))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `Status` (
  `StatusId` INT(15) NOT NULL,
  `height` DECIMAL(6,2) NOT NULL,
  `weight` DECIMAL(6,2) NOT NULL,
  `statusType` VARCHAR(15) NOT NULL,
  `statusDate` DATE NOT NULL,
  `tagId` INT(15) NOT NULL,
  PRIMARY KEY (`StatusId`),
  INDEX `tagId_idx` (`tagId` ASC),
  INDEX `StatusType_idx` (`statusType` ASC),
  INDEX `statusDate_idx` (`statusDate` ASC),
  CONSTRAINT `fk_Status_profile`
    FOREIGN KEY (`tagId`)
    REFERENCES `Profile` (`tagId`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;

INSERT INTO `Profile` (`tagId`, `sex`) 
    VALUES 
    (101, 'male'),
    (102, 'female'),
    (103, 'female'),
    (104, 'female'),
    (105, 'male');

INSERT INTO `Status` (`StatusId`, `height`, `weight`, `statusType`, `statusDate`, `tagId`) 
    VALUES 
    (1, 5.6, 50, 'single', '2016-01-01', 101),
    (2, 5.6, 50, 'engage', '2016-01-02', 101),
    (3, 5.6, 50, 'maried', '2016-01-03', 101),
    (4, 5.6, 50, 'died', '2016-01-04', 101),
    (5, 5.6, 50, 'single', '2016-01-01', 102),
    (6, 5.6, 50, 'engage', '2016-01-02', 102),
    (7, 5.6, 50, 'died', '2016-01-03', 102),
    (8, 5.6, 50, 'single', '2016-01-01', 103),
    (9, 5.6, 50, 'maried', '2016-01-02', 103),
    (10, 5.6, 50, 'single', '2016-01-01', 104),
    (11, 5.6, 50, 'engage', '2016-01-02', 104),
    (12, 5.6, 50, 'single', '2016-01-01', 105); 

我想只展示那些仍然活着并且性别是男性的人。

查询1

SELECT DISTINCT pro.tagId,pro.sex,sts_max.statusType
  FROM Profile AS pro

  LEFT JOIN (
     SELECT tagId, MAX(`statusDate`) AS sts_max_date 
     FROM Status
     GROUP BY tagId 
  ) AS sts ON pro.tagId = sts.tagId

  LEFT JOIN Status AS sts_max ON sts_max.tagId = pro.tagId AND sts.sts_max_date = sts_max.`statusDate`
  WHERE pro.sex='male' AND sts_max.statusType='single' OR sts_max.statusType='engage' OR sts_max.statusType='maried' 
  ORDER BY pro.tagId ASC

我试图在最新日期显示,但它会返回错误的信息

Results

| tagId |    sex | statusType |
|-------|--------|------------|
|   103 | female |     maried |
|   104 | female |     engage |
|   105 |   male |     single |

我想要这样,它应该只返回性别男性

| tagId |    sex | statusType |
|-------|--------|------------|
|   105 |   male |     single |

也许我的SQL查询有点不对

2 个答案:

答案 0 :(得分:0)

谢谢@Strawberry提出你的想法,太棒了。像魅力一样工作

查询已更新

SELECT DISTINCT pro.tagId,pro.sex,sts_max.statusType
  FROM Profile AS pro

  LEFT JOIN (
     SELECT tagId, MAX(`statusDate`) AS sts_max_date 
     FROM Status
     GROUP BY tagId 
  ) AS sts ON pro.tagId = sts.tagId

  LEFT JOIN Status AS sts_max ON sts_max.tagId = pro.tagId AND sts.sts_max_date = sts_max.`statusDate`
  WHERE pro.sex='male' AND (sts_max.statusType='single' OR sts_max.statusType='engage' OR sts_max.statusType='maried') 
  ORDER BY pro.tagId ASC

答案 1 :(得分:0)

也许你可以减少left join。 :d

SELECT DISTINCT pro.tagId,pro.sex, s.statusType
FROM Profile AS pro
LEFT JOIN `Status` AS s
ON pro.tagId = s.tagId 
AND s.statusType IN('single','engage','maried')
AND s.tagId NOT IN (SELECT DISTINCT tagId FROM `Status` WHERE statusType = 'died')
WHERE pro.sex = 'male'
ORDER BY s.statusDate DESC
LIMIT 1

SQLFiddle DEMO HERE