我有一个包含5000行的数据库,其中包含人员,他们有数据及其结果,如下所示:
Table_A
+------+-------+-----+--------+
| Name | team |r_id | result |
+------+-------+-----+--------+
| Jhon | A | 1 | 12.45 |
| Mike | C | 1 | 12.42 |
| Bob | C | 1 | 13.02 |
| ... | ... | ... | ... |
| Alan | F | 1 | 12.53 |
| ... | ... | ... | ... |
| Mac | A | 2 | 5.24 |
| Josh | B | 2 | 3.56 |
| Alan | F | 2 | 4.12 |
| ... | ... | ... | ... |
| Nic | D | 197 | 6.28 |
| Eli | E | 197 | 7.21 |
+------+-------+-----+--------+
另外还有另一个表,rid列是param1的中介(必须是)。
Table_B
+-----+--------+----------+
|r_id | param1 | fooData |
+-----+--------+----------+
| 1 | 1 | A |
| 2 | 3 | B |
| 3 | 4 | A | two r_id set can have the same param1
| 4 | 4 | B |
| 5 | 2 | C |
| 6 | 3 | A |
| 7 | 1 | B |
+-----+--------+----------+
我需要使用"选择&#34 ;.
返回每个组中最好的例如,
SELECT *
FROM Table_A a
LEFT JOIN Table_B b ON a.r_id = b.r_id
ORDER BY IF(b.fooData="A",CAST(result AS DECIMAL(4,3)),myCastFunction(result)) ASC
LIMIT 1
那个函数,用给定的数字(param1)命令每个组内的人,我希望第一行总是按每个组一起,显然是一个很好的表现。
+-------+------+-------+--------+
| group | Name | team | result |
+-------+------+-------+--------+
| 1 | Mike | C | 12.42 |
| 3 | Josh | B | 3.56 |
| ... | ... | ... | ... |
| 194 | Nic | D | 6.28 |
+-------+------+-------+--------+
答案 0 :(得分:2)
模式(MySQL v5.7)
CREATE TABLE table_a (
`Name` VARCHAR(4),
`team` VARCHAR(1),
`r_id` INTEGER,
`result` FLOAT
);
INSERT INTO table_a
(`Name`, `team`, `r_id`, `result`)
VALUES
('Jhon', 'A', '1', '12.45'),
('Mike', 'C', '1', '12.42'),
('Bob', 'C', '1', '13.02'),
('Alan', 'F', '1', '12.53'),
('Mac', 'A', '2', '5.24'),
('Josh', 'B', '2', '3.56'),
('Alan', 'F', '2', '4.12'),
('Nic', 'D', '197', '6.28'),
('Eli', 'E', '197', '7.21');
CREATE TABLE table_b (
`r_id` INTEGER,
`param1` INTEGER,
`fooData` VARCHAR(1)
);
INSERT INTO table_b
(`r_id`, `param1`, `fooData`)
VALUES
('1', '1', 'A'),
('2', '3', 'B'),
('3', '4', 'A'),
('4', '4', 'B'),
('5', '2', 'C'),
('6', '3', 'A'),
('7', '1', 'B');
原始查询
SELECT *
FROM table_a a
LEFT JOIN table_b b ON a.r_id = b.r_id
ORDER BY IF(b.fooData="A",CAST(result AS DECIMAL(4,3)),SIN(result)) ASC
LIMIT 1;
| Name | team | r_id | result | r_id | param1 | fooData |
| ---- | ---- | ---- | ------ | ---- | ------ | ------- |
| Mac | A | 2 | 5.24 | 2 | 3 | B |
查询#2
SELECT ab.*
FROM (
SELECT a.*,
b.param1,
(
@rn := IF(b.param1 = @g, @rn + 1, IF(@g := b.param1, 1, 1) )
) AS rn
FROM table_a a
JOIN table_b b ON a.r_id = b.r_id
CROSS JOIN (
SELECT @g := '', @rn := 0
) params
ORDER BY b.param1, IF(b.fooData="A",CAST(result AS DECIMAL(4,3)),SIN(result)) ASC
) ab
WHERE rn = 1;
| Name | team | r_id | result | param1 | rn |
| ---- | ---- | ---- | ------ | ------ | --- |
| Jhon | A | 1 | 12.45 | 1 | 1 |
| Mac | A | 2 | 5.24 | 3 | 1 |
答案 1 :(得分:0)
您需要联接才能识别这些群组。然后你需要一些方法来选择第一行。我会选择变量:
select ab.*
from (select a.*, b.grp,
(@rn := if(b.grp = @g, @rn + 1,
if(b.grp := @g, 1, 1)
)
) as rn
from table_a a join
table_b b
on a.r_id = b.r_id cross join
(select @g := '', @rn := 0) params
order by b.grp, a.result
) ab
where rn = 1;
答案 2 :(得分:0)
由于mysql不支持分区,最简单的方法可能是使用table_a
中的subselect:
select a.* from
(select distinc group from table_b) grp
inner join table_a a
on a.r_id in (select b.r_id from table_b b where b.group = grp.group) and
result = (
select min(result) from table_a ai where
ai.r_id in (select b.r_id from table_b b where b.group = grp.group)
)