0

私は何日もこれをいじっています。マネージャー、マネージャーが割り当てられているサイト、およびそれらのサイトに割り当てられている栽培者のテーブルがあります。マネージャーが何人の栽培者を持っているかを知る必要があります。マネージャーはサイトに割り当てられていますが、栽培者には割り当てられていないため、このドリルを実行して、特定のマネージャーが持つ個々のサイトに割り当てられた栽培者に基づいて、何人の栽培者がいるかを調べる必要があります。サイトには栽培者が 1 人しかいません。特定のマネージャーの栽培者の数をかなり簡単に取得できますが、各マネージャーの栽培者の数を含む単一のテーブルを返したいのですが、困惑しています。

次のコードがあります。

DECLARE @ManagerID     INT
DECLARE @getManagerID  CURSOR 
SET @getManagerID =  CURSOR FOR
SELECT ID
FROM   Managers

     OPEN @getManagerID
     FETCH NEXT
     FROM @getManagerID INTO @ManagerID
WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT COUNT(Grower) AS NumGrowers
    FROM   Growers
    WHERE  Growers.ID IN 
    (
       SELECT sitesg.Grower
       FROM   SitesG
       WHERE  SitesG.id IN 
       (
          SELECT SITE
          FROM   ManagerSites
          WHERE  ManagerSites.Manager IN 
          (
             SELECT ID
             FROM Managers
             WHERE ID = @ManagerID
          )
       )
    )

    FETCH NEXT
    FROM @getManagerID INTO @ManagerID
END
     CLOSE @getManagerID
     DEALLOCATE @getManagerID

これにより、おそらく一時テーブルに保存できる一連の結果が得られますが、もっと良い方法があるはずです。何か案は?

-ジョー

4

1 に答える 1

1

はい、カーソルとすべてのネストされたサブクエリを捨ててください。これはまさに結合の目的です...

SELECT ManagerID = m.ID, NumGrowers = COUNT(DISTINCT g.ID)
  FROM dbo.Managers AS m
  INNER JOIN dbo.ManagerSites AS s
  ON s.Manager = m.ID
  INNER JOIN dbo.SitesG AS sg
  ON s.SITE = sg.id
  INNER JOIN dbo.Growers AS g
  ON sg.Grower = g.ID
  GROUP BY m.ID;

実際、あなたが気にするのはManagerIDこれを単純化することだけである場合:

SELECT ManagerID = s.Manager, NumGrowers = COUNT(DISTINCT g.ID)
  FROM dbo.ManagerSites AS s
  INNER JOIN dbo.SitesG AS sg
  ON s.SITE = sg.id
  INNER JOIN dbo.Growers AS g
  ON sg.Grower = g.ID
  GROUP BY s.Manager;

余談ですが、 と のようなものを結合するのは非常に紛らわしいs.Manager = m.IDですsg.Grower = g.ID。ものなどを、モデルに現れるすべての場所で同じものManagerIDと呼んでみませんか? GrowerIDこれにより、これらの結合がより直感的になることは間違いありません。

于 2013-01-22T04:49:18.093 に答える