【问题标题】:SQL - Only Return Row If Column Does Not Have Same ValueSQL - 如果列没有相同的值,则仅返回行
【发布时间】:2019-10-25 18:09:01
【问题描述】:

我遇到了一个问题,我试图返回一列中只有 1 个值匹配的行。例如:

CREATE TABLE TEST
(
    ID INT PRIMARY KEY,
    FIRSTNAME VARCHAR(30) NOT NULL,
    LASTNAME VARCHAR(30) NOT NULL,
    EMAIL VARCHAR(50),
    PHONENUMBER VARCHAR(50)
    STAMP DATETIME
)

INSERT INTO TEST VALUES (1, 'Tom', 'Lew', 'tom@hotmail.com', '11111111111', '2019-08-23 15:12:06.807')
INSERT INTO TEST VALUES (2, 'Tom', 'Lew', 'tom@hotmail.com', '22222222222', '2019-08-27 15:12:06.807')
INSERT INTO TEST VALUES (3, 'Jack', 'Stan', 'jstan@hotmail.com', '3333333333', '2019-08-03 15:12:06.807')
INSERT INTO TEST VALUES (4, 'John', 'Doe', 'jdoe@hotmail.com',  '44444444444', '2019-08-13 15:12:06.807')
INSERT INTO TEST VALUES (5, 'Peter', 'Griffin', 'pgriffin@hotmail.com', '55555555555', '2019-07-23 15:12:06.807')
INSERT INTO TEST VALUES (6, 'Homer', 'Simpson', 'hsimpson@hotmail.com', '66666666666', 2019-08-23 15:12:06.807')

SELECT FirstName, LastName, Email, PhoneNumber
FROM TEST GROUP BY FirstName, LastName, Email, PhoneNumber
HAVING COUNT (FirstName) <= 1

所以结果应该返回除“Tom”之外的所有内容,因为“Tom”在 First Name 列中有多个匹配的值。但是,它会返回所有内容。

如果我执行 SELECT FirstName、LastName、Email 和 GROUP BY FirstName、LastName、Email,它会正确返回。

【问题讨论】:

  • 什么是数据库(和版本)?

标签: sql


【解决方案1】:

您可以使用not exists。如果您只关心名字:

select t.*
from test t
where not exists (select 1
                  from t t2
                  where t2.firstname = t.firstname and
                        t2.id <> t.id
                 );

【讨论】:

  • 谢谢,这太完美了。
【解决方案2】:

您的选择查询的问题是两个汤姆没有相同的电话号码。如果您要在 GROUP BY 子句中包含 phonenumber,它将为您提供两个 tom 的 2 个唯一行。您需要为GROUP BY 确定您唯一的复合列。

如果您只关心FirstName,您的查询将是这样的。

SELECT FirstName, LastName, Email, PhoneNumber
FROM TEST GROUP BY FirstName
HAVING COUNT (FirstName) <= 1

如果您将 LastNameEmail 输入GROUP BY,那么:

SELECT FirstName, LastName, Email, PhoneNumber
FROM TEST GROUP BY FirstName, LastName, Email
HAVING COUNT (FirstName) <= 1

【讨论】:

    【解决方案3】:

    由于您检查唯一的FirstNames,因此您应该只检查GROUP BY FirstName 并使用MAX()MIN() 在其他列上聚合(这没有任何区别,因为HAVING 子句中的条件确保这些列中仅存在 1 个值):

    SELECT FirstName, 
      MAX(LastName) LastName, MAX(Email) Email, MAX(PhoneNumber) PhoneNumber
    FROM TEST 
    GROUP BY FirstName
    HAVING COUNT(*) = 1 
    

    请参阅demo
    结果:

    | FirstName | LastName | Email                | PhoneNumber |
    | --------- | -------- | -------------------- | ----------- |
    | Homer     | Simpson  | hsimpson@hotmail.com | 66666666666 |
    | Jack      | Stan     | jstan@hotmail.com    | 3333333333  |
    | John      | Doe      | jdoe@hotmail.com     | 44444444444 |
    | Peter     | Griffin  | pgriffin@hotmail.com | 55555555555 |
    

    【讨论】:

      【解决方案4】:

      我将使用 ROW_NUMBER() 排除重复记录:

      SELECT * FROM(
                    SELECT firstname, lastname, email, phonenumber,
                    ROW_NUMBER() OVER(PARTITION BY firstname ORDER BY firstname) AS rn
                    FROM test
                  )
       WHERE rn=1;
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-12
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2019-12-23
        • 1970-01-01
        • 2022-10-08
        相关资源
        最近更新 更多