SQL一对多或无多对?

时间:2012-10-03 20:52:16

标签: sql-server tsql

我有一对多的加入。工作完美无缺,而且很快。许多表中的一对多可能没有记录。如果是这种情况,我想将它加入到许多表中的所有记录中。

USERS
-----
UserID | Name

CATEGORIES
------------------
CategoryID | CategoryName

USER_CATEGORIES
---------------
UserID | CategoryID

如果没有分配给用户的类别,我想加入所有类别。这背后的原因是,一些用户可能管理所有类别。如果添加了类别,则会自动将其分配给这些用户。

1 | Michael
2 | Bob

100 | Billing
101 | Email
102 | Technical

1 | 101

我希望结果是:

1 | Michael | 101 | Email
2 | Bob | 100 | Billing
2 | Bob | 101 | Email
2 | Bob | 102 | Technical

到目前为止,它的工作方式是:

DECLARE @USERS TABLE (UserID INT, UserName VARCHAR(10));
DECLARE @USER_CATEGORIES TABLE (UserID INT, CategoryID INT);
DECLARE @CATEGORIES TABLE (CategoryID INT, CategoryName VARCHAR(10));

INSERT INTO @USERS (UserID, UserName)
(
    SELECT 1, 'Michael' UNION ALL
    SELECT 2, 'Bob'
)

INSERT INTO @CATEGORIES (CategoryID, CategoryName)
(
    SELECT 100, 'Billing' UNION ALL
    SELECT 101, 'Email' UNION ALL
    SELECT 102, 'Technical'
)

INSERT INTO @USER_CATEGORIES (UserID, CategoryID)
(
    SELECT 1, 101
)

SELECT
  U.UserID
  , U.UserName
  , C2.CategoryID
  , C2.CategoryName
FROM
  @USERS U LEFT JOIN
  @USER_CATEGORIES UC ON U.UserID = UC.UserID LEFT JOIN
  @CATEGORIES C ON UC.CategoryID = C.CategoryID LEFT JOIN
  @CATEGORIES C2 ON C.CategoryID = C2.CategoryID OR (C.CategoryID IS NULL)

这是处理此问题的正确方法吗?当我有许多用户/类别组合时,似乎有点太多开销。

2 个答案:

答案 0 :(得分:1)

您可以将其中一个联接移至@CATEGORIES

SELECT
  U.UserID
  , U.UserName
  , C2.CategoryID
  , C2.CategoryName
FROM @USERS U
  LEFT JOIN @USER_CATEGORIES UC
  ON U.UserID = UC.UserID

  LEFT JOIN @CATEGORIES C2
  ON UC.CategoryID = C2.CategoryID
  OR (UC.CategoryID IS NULL)

答案 1 :(得分:0)

呃,如果你要查询一个类别或一个用户,那么我发现它在审美方面具有攻击性,好吧。

对于所有用户和类别?不适合我,没有

不能说你应该走哪条路。因为我还没有找到你想要这个数据的线索

但是,我要么回复说“所有”'内部联接的结果为null,或者我只是使用它为该用户返回没有记录,如果我需要它而没有从类别中触发select *并且还没有缓存它。