拥有Mysql
数据库,如果变量( TUser.Name, TAccount.Name )
中不存在TUser.name
,我必须选择所有@UserNames
对。
如果存在,我必须仅选择( TUser.Name, TAccount.Name )
中TUser.name
@UserNames
对DECLARE @UserNames = "Alpha, Beta, Gama";
SELECT User.Name
, Account.Name
FROM TUser
, TAccount
, TUserAccount
WHERE TAccount.ID = TUserAccount.AccountID
AND TUserAccount.UserID = User.ID
-- please rewrite this line
AND TUser.Name IN ( IFNULL ( ( SELECT ID FROM TUser WHERE Name IN @UserNames ) , ( SELECT ID FROM TUser ) ) )
。
类似于以下查询的最后一行:
{{1}}
提前谢谢!
答案 0 :(得分:1)
您不能使用您的条件返回互斥结果集,而不使用IF语句:
SELECT @sum := SUM(FIND_IN_SET(u.name, @UserNames))
FROM TUSER u
IF @sum > 0 THEN
SELECT u.name,
a.name
FROM TUSER u
JOIN TUSERACCOUNT ua ON ua.userid = u.id
JOIN TACCOUNT a ON a.id = ua.accountid
WHERE FIND_IN_SET(u.name, @UserNames) > 0
ELSE
SELECT u.name,
a.name
FROM TUSER u
JOIN TUSERACCOUNT ua ON ua.userid = u.id
JOIN TACCOUNT a ON a.id = ua.accountid
END IF;
您可以将其作为PreparedStatement,MySQL的动态SQL,但您仍然需要运行查询以了解是否需要返回全部或子集。
参考文献:
答案 1 :(得分:0)
SELECT
User.Name,
Account.Name
FROM TUser
JOIN TAccount
ON TAccount.Name = TUser.Name
JOIN TUserAccount
ON TUserAccount.AccountID = TAccount.ID
AND TUserAccount.UserID = TUser.ID
LEFT JOIN (
SELECT ID FROM TUser WHERE Name IN @UserNames
) AS UsersFound
ON TUser.ID = UsersFound.ID
那样的东西?我没有测试过它。
答案 2 :(得分:0)
好的,所以这就是我称之为'hacks'而不是normall数据库查询,我不赞成首先处理你必须处理的位置。处理这类项目列表的正确方法是让您的应用程序语言将其解析为一个很好的列表,您可以使用它来构建一个普通的常规SQL IN列表,如下所示:
TUser.Name IN ('Name1', 'Name2',...., 'NameX')
但是无论如何,如果你想坚持原来的问题并且数据库是mysql,你可以在一个查询中以一种远程理智的方式做到这一点:
SET @UserNames := 'Alpha,Beta,Gama';
SELECT TUser.Name
, TAccount.Name
FROM TUser
INNER JOIN TUserAccount
ON TUser.ID = TUserAccount.UserID
INNER JOIN TAccount
ON TUserAccount.AccountID = TAccount.ID
WHERE FIND_IN_SET(TUser.Name, @UserNames)
OR (SELECT COUNT(*)
FROM TUser.Name
WHERE FIND_IN_SET(TUser.Name, @UserNames)) = 0
请注意,我确实更改了输入数据 - 逗号后面没有任何空格。如果这是不可接受的,只需使用@UserNames
更改查询中每次出现的REPLACE(@UserNames, ', ', ',')
即可。另请注意,它的性能很差,因为无法使用TUser.Name上的任何索引来过滤特定用户。
我已经提到你真的应该制作一份正确的IN
数据清单。您也可以直接在SQL中执行此操作(动态SQL):
SET @UserNames := 'Alpha, Beta, Gama';
SET @stmt := CONCAT(
' SELECT TUser.Name'
,' , TAccount.Name'
,' FROM TUser'
,' INNER JOIN TUserAccount'
,' ON TUser.ID = TUserAccount.UserID'
,' INNER JOIN TAccount'
,' ON TUserAccount.AccountID = TAccount.ID'
,' WHERE TUser.Name IN (''', REPLACE(@UserNames, ', ', ''',''') , ''')'
,' OR (SELECT COUNT(*) '
,' FROM TUser.Name'
,' WHERE TUser.Name IN (''', REPLACE(@UserNames, ', ', ''',''') , ''')) = 0'
)
PREPARE stmt FROM @stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
(请注意,在这种情况下,我可以使用未更改空格的用户名列表)