2016-05-20 2 views
2

Мой запрос:SQL Помощь Inner JOIN LEFT JOIN

SELECT Pics.ID, Pics.ProfileID, Pics.Position, Rate.ID as RateID, Rate.Rating, Rate.ProfileID, Gender 
FROM Pics 
    INNER JOIN Profiles ON Pics.ProfileID = Profiles.ID 
    LEFT JOIN Rate ON Pics.ID = Rate.PicID 
WHERE Gender = 'female' 
ORDER BY Pics.ID 

И результаты:

ID ProfileID Position RateID Rating ProfileID Gender 
23 24  1  59  9  42  female 
24 24  2  33  8  32  female 
23 24  1  53  3  40  female 
26 24  4  31  8  32  female 
30 25  4  30  8  32  female 
24 24  2  58  4  42  female 

Теперь я хочу сделать еще один запрос, который был бы: Если Rate.ProfileID = 32, удалить все строки, которые содержат тот же Pics.ID

так осталось:

ID ProfileID Position RateID Rating ProfileID Gender 
23 24  1  59  9  42  female 
23 24  1  53  3  40  female 

, а также удалить все повторяющиеся Pics.ID так только один из указанных выше, поскольку они оба = 23 так осталось:

23 24 1 59 9 42 самок или 23 24 1 53 3 40 женских

+0

Что вы PRIMARY KEY? – Strawberry

+0

Вы что-то пробовали? Когда вы попытались решить вашу проблему до публикации здесь, какие проблемы вы столкнулись? – dfundako

+1

rate.profileID находится слева. Поэтому он должен быть включен в соединение, поэтому исключение сохраняет ваши нулевые значения. поэтому ... 'LEFT JOIN Rate ON Pics.ID = Rate.PicID и Rate.ProfileID = 32', если вы делаете' LEFT JOIN Rate ON Pics.ID = Rate.PicID, где gender = 'female' и Rate.ProfileID = 32 'тогда вы в основном делаете левое соединение внутренним, поскольку вы устраняете нули, сгенерированные из левого соединения в предложении where. Null <> 32! – xQbert

ответ

2

Вы должны, вероятно, избавиться от «магических чисел», как 32. То есть, я думаю, что это даст вам то, что вам нужно.

SELECT 
    P.ID, 
    P.ProfileID, 
    P.Position, 
    R.ID as RateID, 
    R.Rating, 
    R.ProfileID, 
    PR.Gender 
FROM 
    Pics P 
INNER JOIN Profiles PR ON PR.ID = P.ProfileID 
LEFT JOIN Rate R ON R.PicID = P.ID 
WHERE 
    PR.Gender = 'female' AND 
    NOT EXISTS (
     SELECT * 
     FROM Pics P2 
     INNER JOIN Profiles PR2 ON PR2.ID = P2.ProfileID 
     INNER JOIN Rate R2 ON R2.PicID = P2.ID AND R2.ProfileID = 32 
     WHERE 
      P2.ID = P.ID 
    ) 
ORDER BY 
    P.ID 
+0

Большое спасибо, я пробовал другие 2, но это тот, который делает то, что я хотел :) – user2643679

+0

Запрос не нуждается в таблице 'Rate' в подзапросе. –

+0

Это хороший ответ - хорошо выложен. @ user2643679, выполнил ли мой запрос для вас? Он должен делать то же самое. Разве если SQL Server не жаловался на отсутствие псевдонимов в моей? – Sturgus

1

@Shadow Поскольку вторая строка содержит Rate.ProfileID = 32, а это Pic.ID = 24, поэтому он должен удалить ВСЕ Pic.ID = 24, что также удаляет нижнюю строку.

SELECT Pics.ID, Pics.ProfileID, Pics.Position, Rate.ID as RateID, Rate.Rating, Rate.ProfileID, Gender 
FROM Pics 
INNER JOIN Profiles ON Pics.ProfileID = Profiles.ID 
LEFT JOIN Rate ON Pics.ID = Rate.PicID 
WHERE Gender = 'female' AND Pics.ID NOT IN (
    SELECT Pics.ID 
    FROM Pics 
    INNER JOIN Profiles ON Pics.ProfileID = Profiles.ID 
    LEFT JOIN Rate ON Pics.ID = Rate.PicID 
    WHERE Gender = 'female' AND Rate.ProfileID = 32) 

ORDER BY Pics.ID 
0

Попробуйте это:

SELECT Pics.ID, Pics.ProfileID, Pics.Position, Rate.ID as RateID, 
     Rate.Rating, Rate.ProfileID, Gender 
FROM Pics 
INNER JOIN Profiles ON Pics.ProfileID = Profiles.ID 
LEFT JOIN Rate ON Pics.ID = Rate.PicID 
LEFT JOIN Rate AS r 
    ON Rate.ProfileID = r.ProfileID AND Rate.ID > r.ID 
WHERE Gender = 'female' AND (Pics.ProfileID <> 32) AND (r.ID IS NULL) 
ORDER BY Pics.ID 

Последнее LEFT JOIN операция помогает идентифицировать дубликаты, используя этот предикат в ON предложении:

Rate.ProfileID = r.ProfileID 

Если существуют такие дубликаты, как в случае с Rate.ProfileID = 42 , то только тот, который имеет максимумRate.ID, возвращается из-за f Условия ollowing:

Rate.ID > r.ID (`ON` clause) 

и

(r.ID IS NULL) (`WHERE` clause)