MySQL 4.0查询帮助双联接代替子查询

时间:2009-01-28 10:03:14

标签: sql select join limit

选择u.user,g.group,u2g.something     来自用户,群组,u2g     users.u = u2g.u和groups.g = u2g.g

返回如下数据:

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}我的示例数据。

编辑:我在数据中添加了另一列,因为使用分组可能存在不正确的解决方案。

edit2:抱歉,我被文档误导了。 MySQL 4.0不支持子查询:(

edit3:这个SQL将以编程方式为任意数量的组生成(当前规范中最多20个),所以我想避免给出太多额外编码的解决方案。如果找不到解决方案,我只会修改生成的.Net 1.1 DataTable,但我想尽可能避免这种情况。

编辑4:任何新想法?也许没有包含IN(3,5)的子查询?

5 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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

-Edoode

答案 2 :(得分:1)

对groups-table使用双连接将为您提供正确的结果:

  select u.user, u2g.something 
  from   users 
  INNER JOIN u2g ON users.u = u2g.u
  INNER JOIN groups g1 ON u2g.g = g1.g AND g1.group = 3
  INNER JOIN groups g2 ON u2g.g = g2.g AND g2.group = 5
  /* try this for two rows, one for each group */
  INNER JOIN groups ON u2g.g = groups.g

但是,这与您的请求不完全匹配,您需要两行,每行一个。这只会为您提供一行,您可以再次将其与组相关联,从而呈现两行。

另一个例子(如果您选择使用映射的相同groupID):

SELECT u.uID, gm.something 
FROM cdcms_users u 
inner join cdcms_group_memberships gm1 on gm1.uID = u.uID AND gm1.gID = 32
inner join cdcms_group_memberships gm2 on gm2.uID = u.uID AND gm2.gID = 33

答案 3 :(得分:1)

在Oracle中产生两行的非常可怕的非一般解决方案:

  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)
           ;

答案 4 :(得分:1)

为什么groups在查询中使用?其唯一访问的字段(g)存在于u2g中。我想你也许想从那里带回一大堆东西。

为了获得你在不使用子查询的情况下描述的结果集,你最终会得到一个真正的混乱:查询文本的二次爆炸!

您需要以下形式的内容:

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

由于这是一个以编程方式生成的查询,因此我将在此处使用类似网页脚本的符号来描述查询构造。我还将做出草率和无根据的简化假设,即组标识符不是潜在的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]%>
  <% } %>
<% } %>