如何排除重复的行?(删除)



有人可以帮助我执行一个查询,其中删除了查询的重复元素

Select * from table where APPNAME = 'Ap1' or APPNAME= 'Ap2'

使用DISTINCT 的结果

id | APPNAME| USERNAME|
1      Ap1      User1     
2      Ap2      User1    
3      Ap1      User3
4      Ap2      User4
5      Ap1      User5 
6      Ap1      User6 
7      Ap2      User6

在该表中,用户1和6同时具有两个应用程序。这两个用户必须从查询中删除。

预期结果为

id | APPNAME| USERNAME|    
1     Ap1      User3
2     Ap2      User4
3     Ap1      User5

如果我使用DISTINCT,那么它会消除重复,我需要同时消除它们。

使用DISTINCT 的结果

id | APPNAME| USERNAME|
1      Ap1      User1       
2      Ap1      User3
3      Ap2      User4
4      Ap1      User5 
5      Ap2      User6

感谢

select distinct * from table where APPNAME = 'Ap1' or APPNAME= 'Ap2' group by APPNAME having (count(APPNAME)=1);

这似乎应该有效,除非有语法问题(很可能是AS关键字)阻止它在MySQL中工作:

SELECT *
FROM table AS t
WHERE (t.appname = 'Ap1' OR t.appname = 'Ap2')
AND t.username NOT IN
(SELECT u.username
FROM table AS u
WHERE (u.appname = 'Ap1' OR u.appname = 'Ap2')
GROUP BY u.username
HAVING COUNT(*) > 1
)

子查询列出了从列表Ap1Ap2中具有多个条目的用户名,NOT IN将这些用户名从主查询结果中排除。请注意,子查询对appname应用与主查询相同的筛选器,以确保一致性。否则,您可能会忽略具有Ap1Ap3的人,但他们应该包括在内,因为他们只有Ap1Ap2中的一个。

这种子查询方法在MySQL以外的大多数SQL DBMS中都是必要的,这也应该适用于MySQL。可能也有使用OLAP窗口函数的技术。然而,MySQL对于选择列表和GROUP BY子句中允许/需要的内容也有不同的规则——标准SQL要求出现在选择列表中的非聚合列在GROUP BY子句内列出,而大多数SQL DBMS都遵循该规则。据我所知,MySQL没有,这可能允许替代(更简单)的公式——但它们不一定在其他DBMS中工作(这对你来说可能很重要,也可能无关紧要)。

表别名(使用AS关键字引入)并非100%必要;查询在没有它们的情况下工作正常(删除AS [tu]子句并删除t.u.前缀)。针对另一个SQL DBMS(Informix 12.10)进行测试,这是有效的(逐字逐句地——Informix允许将大多数关键字用作对象名称,而不需要将它们视为用双引号括起来的分隔标识符):

DROP TABLE IF EXISTS table;
CREATE TABLE table
(
id          INTEGER NOT NULL PRIMARY KEY,
appname     VARCHAR(10) NOT NULL,
username    VARCHAR(10) NOT NULL
);
INSERT INTO table VALUES(1, 'Ap1', 'User1');
INSERT INTO table VALUES(2, 'Ap2', 'User1');
INSERT INTO table VALUES(3, 'Ap1', 'User3');
INSERT INTO table VALUES(4, 'Ap2', 'User4');
INSERT INTO table VALUES(5, 'Ap1', 'User5');
INSERT INTO table VALUES(6, 'Ap1', 'User6');
INSERT INTO table VALUES(7, 'Ap2', 'User6');
SELECT *
FROM table
WHERE (appname = 'Ap1' OR appname = 'Ap2')
AND username NOT IN
(SELECT username
FROM table
WHERE (appname = 'Ap1' OR appname = 'Ap2')
GROUP BY username
HAVING COUNT(*) > 1
);

输出为:

3   Ap1   User3
4   Ap2   User4
5   Ap1   User5

请注意,我将ID列视为一个物理列,因此从原始数据集中选择值。如果它不是一个物理列,不要在问题中显示它,或者显示它是如何生成的。

最新更新