0

私は一対多の結合を持っています。完璧に、そして迅速に動作します。1 対多では、多テーブルにゼロ レコードが含まれる場合があります。これなら、many テーブルのすべてのレコードに結合したいです。

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)

これはこれを処理する正しい方法ですか?多くのユーザー/カテゴリの組み合わせがある場合、オーバーヘッドが少し多すぎるようです。

4

2 に答える 2

1

への結合の 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)
于 2012-10-03T21:02:05.833 に答える
0

ええと、1 つのカテゴリまたは 1 つのユーザーをクエリしている場合は、美的に不快だと思いますが、わかりました。

すべてのユーザーとカテゴリに対して? 私にとってはそうではありません

どちらに進むべきかは言えません。なぜこのデータが必要なのか見当がつかないからです

しかし、私は内部結合の結果がnullだった「すべて」を返すか、そのユーザーのレコードを返さないだけでそれを使用して、必要でまだ持っていない場合はカテゴリからの選択*をトリガーしますキャッシュしました。

于 2012-10-03T21:09:14.773 に答える