Всеки израз в SQL трябва да препраща към колони само в един ред (с изключение на подзаявки).
A JOIN
може да се използва за създаване на два различни реда в един ред от резултантния набор.
Така че можете да сравнявате стойности на различни редове, като правите самостоятелно присъединяване. Ето един пример, който показва присъединяване на всеки ред към всеки друг ред, свързан със същия клиент (с изключение на присъединяване на ред към себе си):
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
Сега можете да пишете изрази, които сравняват колони. Например, за да ограничите горната заявка до тези, при които поле 1 се различава:
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
WHERE c1.field1 <> c2.field1;
Не посочвате какви сравнения трябва да правите, така че ще оставя това на вас. Ключовият момент е, че като цяло можете да използвате самостоятелно присъединяване, за да сравнявате редове в дадена таблица.
Относно вашите коментари и пояснения:Добре, така че вашата "разлика" не е просто по стойност, а по редовна позиция на реда. Не забравяйте, че релационните бази данни нямат концепция за номер на ред, те имат само ред на редове по отношение на някакъв ред, който трябва да посочите в ORDER BY
клауза. Не бъркайте „id
" псевдоключ с номер на ред, числата се задават като монотонно нарастващи само при съвпадение на изпълнението им.
В MySQL можете да се възползвате от променливи, дефинирани от потребителя за да постигнете ефекта, който търсите. Подредете заявката по clientId
и след това чрез id
и проследяване на стойности на колона в потребителски променливи на MySQL. Когато стойността в текущия ред се различава от стойността в променливата, направете каквото и да подчертаете. Ще покажа пример за едно поле:
SET @clientid = -1, @field1 = '';
SELECT id, clientId, field1, @clientid, @field1,
IF(@clientid <> clientid,
((@clientid := clientid) AND (@field1 := field1)) = NULL,
IF (@field1 <> field1,
(@field1 := field1),
NULL
)
) AS field1_changed
FROM client c
ORDER BY clientId, id;
Обърнете внимание, че това решение не е различно от простото избиране на всички редове с обикновен SQL и проследяване на стойностите с променливи на приложението, докато извличате редове.