子查询在JOIN查询上返回了多个值

时间:2015-05-18 23:47:18

标签: sql sql-server inner-join

我希望从vusers中拆分包含以下数据的行

vusers     branchuserid
name       12,13,10
putra      10,11,9
eko        5
gilang     7,8

tbl_branch

   ID     branch
----------------------
    5     new york
    6     bandung
    7     jakarta
    8     sulawesi
    9     makasar
    10    jalan
    11    menuju
    12    kebenaran
    13    sulit

我想从tbl_branch获取ID,其中ID包含branchuserid

我的查询有问题。我想获得JOIN语句的价值,但它对我不起作用。这是我的查询

 SELECT vUsers.userID, tbl_branch.branch  FROM vUsers JOIN tbl_branch
     ON (SELECT Split.Data.value('.', 'VARCHAR(100)') AS BranchID FROM
     (Select CAST('<M>' + REPLACE(userAccessbranch,',', '</M><M>')+ '</M>'
     AS XML) AS String FROM vUsers) AS Data CROSS APPLY String.nodes ('/M')
     AS Split(Data)) = tbl_branch.ID

2 个答案:

答案 0 :(得分:1)

要确保从子查询中只获取一条记录,您只能使用TOP 1

返回一条记录
SELECT vUsers.userID, tbl_branch.branch
FROM vUsers
JOIN tbl_branch ON (SELECT TOP 1 Split.Data.value('.', 'VARCHAR(100)') AS BranchID
                     FROM (Select TOP 1 CAST('<M>' + REPLACE(userAccessbranch,',', '</M><M>')+ '</M>'AS XML) AS String
                           FROM vUsers) AS Data
                     CROSS APPLY String.nodes ('/M') AS Split(Data)) = tbl_branch.ID

答案 1 :(得分:0)

基本上,您的连接表达式具有以下模式:

row set = scalar value

其中 row set 是您的(SELECT Split.Data.value...)子查询和 scalar value tbl_branch.ID

解决此问题的最简单方法是翻转谓词的边,并将=替换为IN= ANY。所以,它可能是

ON tbl_branch.ID IN (SELECT Split.Data.value...)

ON tbl_branch.ID = ANY (SELECT Split.Data.value...)

但是,数组不是SQL(或特别是Transact-SQL)最强大的一面。该语言旨在用于行集而不是数组。您应该考虑更改架构。在这种情况下,junction table将是一种典型的方法。有了它,你将有三个表:

  • Users

    UserID  UserName
    ------  --------
    1       Putra
    2       Eko
    ...     ...
    
  • Branches

    BranchID  BranchName
    --------  ----------
    5         New York
    6         Bandung
    7         Jakarta
    ...       ...
    
  • UserBranches

    UserID  BranchID
    ------  --------
    1       10
    2       5
    1       11
    ...     ...
    

解决你的问题就像这样微不足道:

SELECT
  u.UserName,
  b.BranchName
FROM
  dbo.Users AS u
  INNER JOIN dbo.UserBranches AS ub ON u.UserID = ub.UserID
  INNER JOIN dbo.Branches AS b ON ub.BranchID = b.BranchID
;