0

users.u = u2g.u および groups.g = u2g.g の場合、users、groups、u2g から u.user、g.group、u2g.something を選択します。

次のようなデータを返します。

user, group, something
----------------------
1   , 3,     a
1   , 5,     b
2   , 3,     c
3   , 3,     d
4   , 5,     e

ここで、グループ 3 とグループ 5の両方に属するユーザーのみを表示するように、このクエリを制限したいと思います。したがって、サンプル データでは {1,3, a} 、 {1,5, b} のみが返されます。 .

編集: group by を使用した不適切なソリューションがある可能性があるため、データに別の列を追加しました。

edit2: 申し訳ありませんが、ドキュメントに惑わされました。MySQL 4.0 はサブクエリをサポートしていません :(

edit3: この SQL は、任意の数のグループ (現在の仕様では最大 20) に対してプログラムで生成されるため、追加のコーディングが多すぎるソリューションは避けたいと思います。解決策が見つからない場合は、結果の .Net 1.1 DataTable を変更するだけですが、可能であればそれを避けたいと考えています。

edit4: 何か新しいアイデアはありますか? おそらく、IN (3,5) を含むサブクエリのないものでしょうか?

4

5 に答える 5

1

groups-table で二重結合を使用すると、正しい結果が得られます。

  u.user、u2g.something を選択
  ユーザーから
  INNER JOIN u2g ON users.u = u2g.u
  INNER JOIN グループ g1 ON u2g.g = g1.g AND g1.group = 3
  内部結合グループ g2 ON u2g.g = g2.g AND g2.group = 5
  /* グループごとに 1 つずつ、2 つの行でこれを試してください */
  INNER JOIN groups ON u2g.g = groups.g

ただし、これは、各グループに 1 つずつ、2 つの行が必要であるという要求と完全には一致しません。これにより 1 行しか表示されませんが、2 行をレンダリングするためにもう一度グループに結合できる場合があります。

別の例 (に対してマップするのと同じ groupID を使用して選択している場合):

SELECT u.uID、gm.something
FROM cdcms_users u
内部結合 cdcms_group_memberships gm1 on gm1.uID = u.uID AND gm1.gID = 32
内部結合 cdcms_group_memberships gm2 on gm2.uID = u.uID AND gm2.gID = 33
于 2009-01-28T10:45:13.327 に答える
1

これらの線に沿った何か?

select u.[user], g.group
from     u
    inner join ug on ug.userid = u.id   
    inner join g on g.id = ug.groupid
    inner join 
    (
        select ug.userid
        from ug
        where ug.groupid in (1,2)
        group by ug.userid
        having count(*) = 2
    ) sub on sub.userid = u.id

-エドード

于 2009-01-28T10:34:32.430 に答える
1

Oracleで2行になる非常に恐ろしい非一般的なソリューション:

  select users.u, groups.g
    from   users , groups, u2g, groups g2, u2g u2g2
    where  users.u = u2g.u 
           and users.u = u2g2.u
           and groups.g = u2g.g
           and g2.g = u2g2.g
           and (groups.g in (3,5) and g2.g in (3,5) and groups.g <> g2.g)
           ;
于 2009-01-28T11:52:31.447 に答える
1
select u.user, g.group, u2g.something 
from users u, groups g, u2g 
where u.user = u2g.user and g.group = u2g.group 
    where exists 
     (select 1 
         from u2g u2g2 
        where u2g2.user=u.user and u2g2.group in(3,5))
于 2009-01-28T10:16:33.883 に答える
1

なぜgroupsクエリで使用されるのですか? その唯一のアクセス フィールド ( g) は に存在しu2gます。おそらくそこから大量のものを持ち帰りたいと思うでしょう。

サブクエリを使用せずに記述したような結果セットを取得するには、クエリ テキストの 2 次爆発という実際の混乱が発生します。

次の形式のものが必要になります。

select users.u, groups.g, u2g0.something
from users u, groups g, u2g u2g0, u2g u2g1
where groups.g = 3
     and users.u = u2g0.u
     and u2g0.g = 3
     and users.u = u2g1.u
     and u2g1.g = 5
union all
select users.u, groups.g, u2g1.something
from users u, groups g, u2g u2g0, u2g u2g1
where groups.g = 5
     and users.u = u2g0.u
     and u2g0.g = 3
     and users.u = u2g1.u
     and u2g1.g = 5

これはプログラムによって生成されたクエリであるため、ここでは Web ページ スクリプトのような表記法を使用してクエリの構造を説明します。また、グループ ID は潜在的な SQL インジェクション攻撃ベクトルではないという軽率で不当な単純化の仮定を立てます。:-)

<% for(int i = 0; i < requiredGroups.Length; i++) { %>
  <% if(i > 0) { %>
    union all
  <% } %>
select users.u, groups.g, u2g<%=i%>.something
from users u, groups g
  <% for(int j = 0; j < requiredGroups.Length; j++) { %>
     , u2g u2g<%=j%>
  <% } %>
where groups.g = <%=requiredGroups[i]%>
  <% for(int j = 0; j < requiredGroups.Length; j++) { %>
     and users.u = u2g<%=j%>.u
     and u2g<%=j>.g = <%=requiredGroups[j]%>
  <% } %>
<% } %>
于 2009-01-29T23:16:21.340 に答える