没有聚合函数的关系代数

时间:2015-10-05 08:45:35

标签: sql aggregate-functions relational-algebra

我们有一个表值为

的表Phone
(Name, Number)
--------------
(John, 123)
(John, 456)
(Bravo, 789)
(Ken, 741)
(Ken, 589)

如果问题是找到只使用一个号码的人,答案是Bravo。

我使用aggregate函数解决了这个问题。但是我不知道如何在不使用聚合函数的情况下解决。

5 个答案:

答案 0 :(得分:4)

这是我的解决方案:

SELECT *
FROM test t
WHERE NOT EXISTS (
        SELECT 1
        FROM test
        WHERE NAME = t.NAME
            AND number <> t.number);

示例SQLFiddle

我不确定关系代数中的这种表示(并且它很可能不正确或完整但它可能会给你一个起点):

RESULT = {(name, number) ∈ TEST | (name, number_2) ¬∃ TEST, number <> number_2}

(这是主要的想法,你可以尝试和have a look here尝试正确地重写它,因为我已经在关系代数中写了10多年了。)

或许你正在寻找一种不同类型的表现形式,like this one here

答案 1 :(得分:1)

您可以使用LEFT JOIN并在JOIN中使用相同的表格,如下所示..

    SELECT a.NAME, a.NUMBER FROM test a 
    LEFT JOIN test b ON a.name = b.name AND a.number <> b.number
    WHERE b.name IS NULL;

希望这会有所帮助。 :)

答案 2 :(得分:0)

如果您使用的是Access-SQL,请尝试以下操作 -

SELECT Name
FROM Phone
GROUP BY Name
HAVING COUNT(Name) = 1;

否则,请尝试 -

SELECT Name
FROM Phone
WHERE COUNT(Name) = 1;

如果您有任何疑问,请随时回复。

答案 3 :(得分:0)

您可以利用RANK()函数,如下所示。

SELECT * FROM @Tbl WHERE Name NOT IN(
SELECT Name FROM (
SELECT  Name, RANK() OVER(PARTITION BY Name ORDER BY Id) AS Rank
FROM @Tbl) t
WHERE t.Rank > 1)

此方法的唯一缺点是,您需要使用表中的唯一ID来获得正确的结果。

SQLFiddle

答案 4 :(得分:-1)

另一种方法是:

select Name from Phone p
where (select name from Phone p2 where p.name = p2.name and p2.number <> p.number limit 1) is null

编辑:添加限制1以确保子选择返回标量