消除重复项并检索每个ID的最大值

时间:2012-01-10 20:14:04

标签: mysql

我有一张这样的表:

ID     Signal    Station    Owner
111     -120      Home      M1
111     -120      Home      M1
111     -120      Home      M2
111     -120      Car       M1
111     -120      Car       M2
111     -120      Work      M1
111    -120       Dept      M3
111     -130      Car       M1
111     -135      Work      M2
222     -98       Home      M2
222     -95       Work      M1
222     -103      Work      M2

我只需要Query来返回每个ID的最大信号:如果Signal相等则随机显示一个。但是如果Signal对多个站点和所有者的信号相同,则下面的查询返回重复。请帮我解决这个问题。所有字段都在同一张表中

ID    Signal    Station    Owner
111    -120       Dept        M3       
111    -120       Home        M1      
111    -120       Work        M2      
222    -95        Work        M1 

但我需要没有重复的条目

Here is the SQL:

SELECT g.ID, g.MaxSignal, g.Station, g.OwnerID FROM (SELECT id, MAX(Signal) AS  
MaxSignal FROM t GROUP BY id) AS g inner join t ON g.id = t.id AND g.MaxSignal = t.Signal;

4 个答案:

答案 0 :(得分:1)

以下是您需要的查询:

SELECT DISTINCT B.* FROM
(SELECT ID,`Signal`,MIN(CONCAT(Station,'-',Owner)) MaxStationOwner
FROM (SELECT DISTINCT t.* FROM  
(SELECT ID,MAX(`Signal`) `Signal` FROM t GROUP BY ID) AAA 
LEFT JOIN t USING (ID,`Signal`)) AA
GROUP BY ID,`Signal`) A
INNER JOIN t B
ON A.MaxStationOwner=CONCAT(B.Station,'-',B.Owner)
AND A.ID=B.ID AND A.`Signal`=B.`Signal`;

以下是您的示例数据:

drop database if exists preeti; 
create database preeti; 
use preeti 
create table t  
(ID int not null,  
`Signal` int not null,  
Station varchar(10),  
Owner varchar(10));  
insert into t values  
(111,     -120 ,     'Home' , 'M1' ),
(111,     -120 ,     'Home' , 'M1' ),
(111,     -120 ,     'Home' , 'M2' ),
(111,     -120 ,     'Car'  , 'M1' ),
(111,     -120 ,     'Car'  , 'M2' ),
(111,     -120 ,     'Work' , 'M1' ),
(111,    -120  ,     'Dept' , 'M3' ),
(111,     -130 ,     'Car'  , 'M1' ),
(111,     -135 ,     'Work' , 'M2' ),
(222,     -98  ,     'Home' , 'M2' ),
(222,     -95  ,     'Work' , 'M1' ),
(222,     -103 ,     'Work' , 'M2' );

以下是您加载的示例数据:

mysql> drop database if exists preeti;
Query OK, 1 row affected (0.03 sec)

mysql> create database preeti;
Query OK, 1 row affected (0.00 sec)

mysql> use preeti
Database changed
mysql> create table t
    -> (ID int not null,
    -> `Signal` int not null,
    -> Station varchar(10),
    -> Owner varchar(10));
Query OK, 0 rows affected (0.06 sec)

mysql> insert into t values
    -> (111,     -120 ,     'Home' , 'M1' ),
    -> (111,     -120 ,     'Home' , 'M1' ),
    -> (111,     -120 ,     'Home' , 'M2' ),
    -> (111,     -120 ,     'Car'  , 'M1' ),
    -> (111,     -120 ,     'Car'  , 'M2' ),
    -> (111,     -120 ,     'Work' , 'M1' ),
    -> (111,    -120  ,     'Dept' , 'M3' ),
    -> (111,     -130 ,     'Car'  , 'M1' ),
    -> (111,     -135 ,     'Work' , 'M2' ),
    -> (222,     -98  ,     'Home' , 'M2' ),
    -> (222,     -95  ,     'Work' , 'M1' ),
    -> (222,     -103 ,     'Work' , 'M2' );
Query OK, 12 rows affected (0.06 sec)
Records: 12  Duplicates: 0  Warnings: 0

mysql>

这是输出:

mysql> SELECT DISTINCT B.* FROM
    -> (SELECT ID,`Signal`,MIN(CONCAT(Station,'-',Owner)) MaxStationOwner
    -> FROM (SELECT DISTINCT t.* FROM
    -> (SELECT ID,MAX(`Signal`) `Signal` FROM t GROUP BY ID) AAA
    -> LEFT JOIN t USING (ID,`Signal`)) AA
    -> GROUP BY ID,`Signal`) A
    -> INNER JOIN t B
    -> ON A.MaxStationOwner=CONCAT(B.Station,'-',B.Owner)
    -> AND A.ID=B.ID AND A.`Signal`=B.`Signal`;
+-----+--------+---------+-------+
| ID  | Signal | Station | Owner |
+-----+--------+---------+-------+
| 111 |   -120 | Car     | M1    |
| 222 |    -95 | Work    | M1    |
+-----+--------+---------+-------+
2 rows in set (0.02 sec)

mysql>

试一试!!!

CAVEAT

确保您在表t上有这个索引:

ALTER TABLE t ADD INDEX ID_Signal_Index (ID,`Signal`);

答案 1 :(得分:0)

我认为你可以使用:

SELECT `ID`, MAX(`Signal`), `Station`, `OwnerID` FROM `table_name` GROUP BY `ID`

而不是您的查询

答案 2 :(得分:0)

在第一次选择后尝试使用distinct:

SELECT DISTINCT g.ID, g.MaxSignal, t.Station, t.OwnerID 
FROM 
(
    SELECT id, MAX(Signal) AS  MaxSignal 
    FROM t 
    GROUP BY id
) AS g 
INNER JOIN t ON g.id = t.id AND g.MaxSignal = t.Signal;

这适用于显示的示例数据,但在行具有相同ID和(最大)信号但具有不同的站或所有者值或两者的值时不起作用。在SQL Server中,我会通过使用ROW_COUNT函数解决问题(在mysql中是否有等效的函数?):

SELECT Id, MaxSignal, Station, OwnerID
FROM
(
    SELECT 
        g.ID, 
        g.MaxSignal, 
        t.Station, 
        t.OwnerID ,
        ROW_NUMBER() OVER(PARTITION BY g.ID, g,MaxSignal ORDER BY t.Station) AS RowNumber
    FROM 
    (
        SELECT id, MAX(Signal) AS  MaxSignal 
        FROM t 
        GROUP BY id
    ) AS g 
    INNER JOIN t ON g.id = t.id AND g.MaxSignal = t.Signal
) AS T1
WHERE RowNumber = 1

答案 3 :(得分:0)

SELECT DISTINCT g.ID, g.MaxSignal, t.Station, t.OwnerID 
FROM (SELECT id, MAX(Signal) AS MaxSignal 
      FROM t 
      GROUP BY id) AS g 
    INNER JOIN t 
        ON g.id = t.id 
             AND g.MaxSignal = t.Signal;