2011-04-19 104 views
0

我正在一个数据库上可以synthetized像:如何从数据库中选择一组特定元素?

TAB1: NICK, COUNTRY 
TAB2: PLAYER, FRIEND 

在TAB2,播放器和朋友都可以连接到各自的一个TAB1.NICK; NICK是主键,PLAYER和FRIEND都是外键。

我需要找到多少玩家朋友只与来自同一个国家的人,但一对夫妇下午,我依然不能管理做到这一点之后......

我想的最后一件事:

select count(*) from TAB1 as p1 
join TAB2 as f1 on p1.nick = f1.player 
join TAB1 as p2 on f1.friend = p2.nick 
where p1.country is not null and p2.country is not null 
and p1.country = p2.country 
and not exists (select * from TAB1 as p0 
    join TAB2 as f0 on p0.nick = f0.nick 
    join TAB1 as p3 on f0.friend = p3.nickname 
    where p0.country is not null and p3.country is not null 
    and p0.country <> p3.country) 
+0

没有PK/FK在这里? – hsz 2011-04-19 15:47:19

+0

请问数据库模式? (特别关系) – 2011-04-19 15:48:52

+0

编辑,遗憾的东西。 – Gurzo 2011-04-19 15:50:14

回答

3

建立查询up-meal - 从容易的部分开始,并继续更难。使其工作的关键观察是您需要对同一个表使用两个连接。该查询给出对的列表,其中两人来自同一个国家:

SELECT p1.nick, p1.country, p2.nick, p2.country 
    FROM tab2 
    JOIN tab1 AS p1 ON tab2.player = p1.nick 
    JOIN tab1 AS p2 ON tab2.friend = p2.nick 
WHERE p1.country = p2.country 

这计数的玩家有一个或更多的朋友来自同一个国家的数量:

SELECT COUNT(DISTINCT p1.nick) 
    FROM tab2 
    JOIN tab1 AS p1 ON tab2.player = p1.nick 
    JOIN tab1 AS p2 ON tab2.friend = p2.nick 
WHERE p1.country = p2.country 

而且,如果你所追求的是那些只有来自同一国家的朋友的人(如评论中所建议的那样),那么你需要确定该玩家没有朋友的国家不是玩家的国家。你会进入一个有趣的问题:一些没有朋友的人会被计算在内吗?因为他们没有任何朋友来自同一个国家,他们不是通过下面的查询统计:

SELECT COUNT(DISTINCT p1.nick) 
    FROM tab2 
    JOIN tab1 AS p1 ON tab2.player = p1.nick 
    JOIN tab1 AS p2 ON tab2.friend = p2.nick 
WHERE p1.country = p2.country 
    AND NOT EXISTS 
      (SELECT * 
       FROM tab2 AS t2 
       JOIN tab1 AS p3 ON t2.player = p3.nick 
       JOIN tab1 AS p4 ON t2.friend = p4.nick 
      WHERE p3.country != p4.country 
       AND p3.nick = p1.nick 
      ) 

这是说“球员谁从他们自己的国家至少一个朋友那里没有朋友来自不同国家的球员“。

+0

这不仅仅表明有同一个国家的朋友的人,而不是那些只有**的朋友来自同一个国家的朋友?我想他也需要一个“不存在”的东西。 – JNK 2011-04-19 15:51:01

+0

JNK是正确的,这个查询只包括来自同一个国家的朋友,并不考虑来自不同地方的朋友。 – Gurzo 2011-04-19 15:56:21

+0

@JNK,@Gurzon:作出的编辑...像往常一样,如果您分阶段进行复杂查询,则很容易。感谢您指引我向右(或更接近右)的方向。 – 2011-04-19 16:03:07

1
SELECT TAB2.PLAYER, TAB1.COUNTRY 
    FROM TAB2 PLAYER_TAB2 
    JOIN TAB1 PLAYER_TAB1 ON TAB1.NICK = TAB2.PLAYER 
WHERE NOT EXISTS (SELECT NULL 
        FROM TAB2 
        JOIN TAB1 ON TAB1.NICK = TAB2.FRIEND 
           AND TAB1.COUNTRY != PLAYER_TAB1.COUNTRY 
        WHERE TAB2.PLAYER = PLAYER_TAB2.PLAYER) 
+0

+1 - 我认为这是OP之后的事情。 – JNK 2011-04-19 15:57:28