User 13204940 Ответов: 1

Выбор данных только в том случае, если существуют связанные данные


Привет,

У меня есть следующий запрос, чтобы вернуть массовый запрос "существует" для нескольких записей. То, что я хочу сделать, - это только выбрать u.role и несколько других полей, если имя пользователя существует в разделе "пользователи". Этот метод работает, но он запутан, так как я проверяю, существует ли имя пользователя для каждого столбца, который я выбираю. Есть ли более компактный способ сказать;

Если имя пользователя существует, верните столбец role, x, y, z и т. д.
В противном случае верните NULL для столбца role, x, y, z и т. д.

CREATE TEMPORARY TABLE _users(username varchar(256));
        INSERT INTO _users VALUES('testuser1', 'testuser2');
        SELECT _u.username,
        CASE
                WHEN ISNULL(u.username) = 1 THEN 0
                ELSE 1
        END 'exists',
        CASE
                WHEN ISNULL(u.username) = 1 THEN u.role
                ELSE NULL
        END 'role'
        FROM _users _u
        LEFT JOIN users u
        ON u.username = _u.username;
        DROP TABLE _users


Что я уже пробовал:

-------------------------------------------------------------------------------

[no name]

Я уже говорил, что запрос работает отлично. Я использую MySQL, который имеет только один параметр для ISNULL.

Richard Deeming

Где в вашем вопросе Вы упомянули MySQL?

Вы могли бы, по крайней мере, использовать тег "MySQL", а не общий тег "SQL". MySQL имеет так много отличий от обычного SQL, что это может быть и другой язык.

1 Ответов

Рейтинг:
1

Maciej Los

Я бы рекомендовал прочитать это: Существует (Transact-SQL)[^]

[РЕДАКТИРОВАТЬ]
Если вы хотите вернуться NULL, вы можете использовать этот трюк:
SELECT TOP(1) Field1, Field2, Field3
FROM YourTable
WHERE UserName = 'Whatever'
UNION ALL
SELECT NULL AS Field1, NULL AS Field2, NULL As Field3


Но - я не рекомендую этого делать по нескольким причинам...

Вот "рабочий" пример:
DECLARE @t TABLE (uName VARCHAR(30))
INSERT INTO @t (uName)
VALUES('A'), ('B'), ('C')

SELECT TOP(1) uName
FROM @t
WHERE uName = 'D'
UNION ALL
SELECT NULL AS uName

--returns: NULL


[Править 2]
Согласно нашей дискуссии, а LEFT JOIN делает именно то, чего вы ожидаете достичь. Видеть:
DECLARE @tmp TABLE (uName VARCHAR(30))
INSERT INTO @tmp (uName)
VALUES('A'), ('B'), ('C')


DECLARE @orig TABLE (uName VARCHAR(30), [role] VARCHAR(30))
INSERT INTO @orig (uName, [role])
VALUES('A', 'admin'), ('D', 'user'), ('C', 'user')

SELECT t.uName AS TmpName, o.*
FROM @tmp t LEFT JOIN @orig o ON t.uName = o.uName 

Результат:
TmpName	uName	role
A		A		admin
B		NULL	NULL
C		C		user


Для получения более подробной информации, пожалуйста, смотрите: Визуальное представление SQL-соединений[^]


[no name]

Меня беспокоит не то, что существует, а логика.

Maciej Los

Проверьте обновленные ответ ;)

[no name]

Нет - нет, ты не понимаешь, о чем я прошу.

Запрос у меня уже работает. Повторяющийся "случай, когда ISNULL(u.username) = 1 THEN" является грязным, я не хочу делать это для каждого столбца, который я хочу вернуть. Я хочу одного, если заявление, то в случае каждого из имен в временная таблица существует в 'пользователи', выберите U.роль, х, у, Z. Если каждый из них не существует, верните NULL, NULL, NULL, NULL

Maciej Los

Смотрите мой ответ еще раз.