2016-06-15 14 views
1

Ich habe zwei Tabellen, Profile und Status, für Human Info.Mysql Complex Abfrage fehlgeschlagen

Ich habe eine eindeutige TagId für jeden Menschen in der Profile Tabelle gespeichert und ich habe mehrere Datensätze auf Status Tabelle gespeichert.

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); 

ich nur Personen sehen möchte, die noch am Leben sind und dessen Geschlecht 'männlich'

Abfrage 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 

ich zu zeigen versucht, auf Neueste Datum basiert Aber es wird falsche Informationen zurückgeben

Results:

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

ich so will, sollte es nur Sex männlich

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

Vielleicht My SQL-Abfrage wenig falsch

+1

Sie Klammern getrennte Argumente artikulieren können: WHERE x = 1 und (y = 2 oder z = 3) ' – Strawberry

+0

@Reno, für 101 spätestes Datum bereits gestorben, Ich möchte nicht zeigen, starb ein –

+0

Dank @Strawberry, seine funktioniert wie Charme :) –

Antwort

0

Dank @Strawberry Für geben Sie Ihre Idee zurückkehren , genial . Arbeiten wie ein Charme

Abfrage Aktualisiert:

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 
0

Vielleicht haben Sie eine left join reduzieren. : 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

+0

Ich möchte nicht überprüfen LIMIT zu verwenden, könnte es viel männliches Geschlecht sein Wenn ich LIMIT entferne, wird es NULL Ergebnis hinzufügen [Siehe SQL Fiddle] (http: // sqlfid dle.com/#!9/bf3ee5/16) –

+0

In diesem Fall können Sie 'linker Join' in' innerer Join' ändern, und was Sie genau wollen, ist der Record 'group by tabId', oder? – Blank