#sql #sql-server
#sql #sql-сервер
Вопрос:
В SQL Server у меня есть одна таблица со следующими данными (tblUserSettings):
| CountryID | CityID | UserType | Value1 | Value2 | Value3 |
| 9 | 3 | 1 | 5 | 5 | 5 |
| 9 | 3 | 2 | NULL | NULL | NULL |
| 9 | 3 | 3 | 5 | 5 | 5 |
| 9 | 3 | 4 | 5 | 5 | 5 |
| 9 | 20 | 1 | 5 | 5 | 5 |
| 9 | 20 | 2 | NULL | NULL | NULL |
| 9 | 20 | 3 | 5 | 5 | 5 |
| 9 | 20 | 4 | 0 | 0 | 0 |
Мне нужно сравнить все значения для всех типов пользователей из CityId = 20 со всеми значениями для соответствующих типов пользователей из CityId = 3. Идентификатор страны = 9. Сравниваемые столбцы: Значение1, Значение2, Значение3.
Мне просто нужно знать, все ли они сопоставлены друг с другом или нет. Я попытался сделать что-то следующим образом:
SELECT CASE WHEN ISNULL(t1.Value1, 0) = ISNULL(t2.Value1, 0) THEN 1 ELSE 0 END AS Match1,
CASE WHEN ISNULL(t1.Value2, 0) = ISNULL(t2.Value2, 0) THEN 1 ELSE 0 END AS Match2,
CASE WHEN ISNULL(t1.Value3, 0) = ISNULL(t2.Value3, 0) THEN 1 ELSE 0 END AS Match3
FROM tblUserSettings t1
INNER JOIN tblUserSettings t2 ON t1.CountryID = t2.CountryID
AND t1.UserType = t2.UserType
AND t1.CityID = 3
AND t2.CityID = 20
WHERE t1.CountryID = 9
И это дает мне следующий результат, который я должен обработать дальше, чтобы определить, все ли совпадает или нет.
| Match1 | Match2 | Match3 |
| 1 | 1 | 1 |
| 1 | 1 | 1 |
| 1 | 1 | 1 |
| 0 | 0 | 0 |
Могу ли я сделать это таким образом, чтобы на выходе был только один столбец и строка — просто получите либо 1 для всех совпадений, либо 0, если хотя бы одно не совпадает?
Комментарии:
1. как должен выглядеть результат?
Ответ №1:
Если вы хотите получить только один столбец, 1
когда все значения совпадают, и 0
если хотя бы одно из них не совпадает, используйте,
SELECT
CASE WHEN ISNULL(t1.Value1, 0) = ISNULL(t2.Value1, 0)
AND ISNULL(t1.Value2, 0) = ISNULL(t2.Value2, 0)
AND ISNULL(t1.Value3, 0) = ISNULL(t2.Value3, 0)
THEN 1 ELSE 0 END AS Match
FROM tblUserSettings t1
INNER JOIN tblUserSettings t2 ON t1.CountryID = t2.CountryID
AND t1.UserType = t2.UserType
AND t1.CityID = 3
AND t2.CityID = 20
WHERE t1.CountryID = 9
Комментарии:
1. Да, это именно то, что я ищу.
2. На самом деле, он по-прежнему дает мне 4 строки для каждого типа пользователя. Я изменил этот запрос и добавил SUM() перед РЕГИСТРОМ, чтобы на выходе была только 1 строка.
3. функция sum() не требуется. Просто используйте
distinct
.4. Да, но если я использую distinct, то, если есть некоторые различия в UserType, будет две строки вместо одной. (одно с 1, а другое с 0)
5. Для usertype 4 значения не совпадают. Поэтому для этой строки должно быть 0. Если вы подведете итог, это будет 1, что означает, что все значения совпадают, а это не то, что вам нужно, я думаю.
Ответ №2:
Если вы хотите сравнить все города, а не только два, вы должны быть в состоянии сделать это путем группировки, а не объединения.
Что-то вроде:
SELECT
CASE WHEN
max(Value1)-min(Value1) = 0
AND max(Value2)-min(Value2) = 0
AND max(Value3)-min(Value3) = 0
THEN 1 ELSE 0 AS Match
FROM tblUserSettings
GROUP BY CountryID,UserType