我有一个看起来像这样的表:
+----+-------+---------+--------+--------+
| id | meta1 | meta2 | value1 | value2 |
+----+-------+---------+--------+--------+
| 1 | foo | bar | 0.1 | 0.01 |
| 1 | baz | quux | 0.2 | 0.01 |
| 1 | lorem | ipsum | 0.1 | 0.05 |
| 2 | dolor | sit | 0.2 | 0.02 |
| 2 | amet | eos | 0.3 | 0.02 |
| 3 | clita | corpora | 0.5 | 0.03 |
+----+-------+---------+--------+--------+
我正在尝试为每个具有最低value1
的ID提取一个(完整的)行,如果有相等的value1
s,则返回到最低值2.
查询应该产生如下结果集:
+----+-------+---------+--------+--------+
| id | meta1 | meta2 | value1 | VALUE2 |
+----+-------+---------+--------+--------+
| 1 | foo | bar | 0.1 | 0.01 |
| 2 | dolor | sit | 0.2 | 0.02 |
| 3 | clita | corpora | 0.5 | 0.03 |
+----+-------+---------+--------+--------+
我首先尝试以下查询:
SELECT
t1.*
FROM
test t1
INNER JOIN
(SELECT
id, MIN(value1) minValue1
FROM
test
GROUP BY id) t2 ON t1.id = t2.id
AND t1.value1 = t2.minValue1;
但这并没有为'1'打破“平局”,我最终得到了两条记录。我已经尝试添加HAVING子句和其他子查询,并且在此初始步骤之后丢失了。非常感谢。
答案 0 :(得分:2)
您希望所有没有更好记录的记录(即具有较低的值1或相同的值1和较低的值2)存在:
select *
from mytable
where not exists
(
select *
from mytable better
where better.id = mytable.id
and
(
better.value1 < mytable.value1
or
(better.value1 = mytable.value1 and better.value2 < mytable.value2)
)
);
答案 1 :(得分:1)
您可以使用not exists
:
SELECT t.*
FROM test t
WHERE NOT EXISTS (SELECT 1
FROM test t2
WHERE t2.id = t.id AND
(t2.value1 < t.value1 OR
(t2.value1 = t.value1 and t2.value2 < t.value2) )
);
另一种方法是使用变量:
select t.*
from (select t.*,
(@rn := if(@i = id, @rn + 1,
if(@i := id, 1, 1)
)
) as rn
from test t cross join
(select @rn := 0, @i := -1) params
order by id, value1, value2
) t
where rn = 1;
答案 2 :(得分:0)
考虑以下内容......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL
,meta1 VARCHAR(12)
,meta2 VARCHAR(12)
,value1 DECIMAL(5,2)
,value2 DECIMAL(5,2)
);
INSERT INTO my_table VALUES
(1 ,'foo','bar',0.1,0.09),
(1 ,'baz','quux',0.2,0.08),
(1 ,'lorem','ipsum',0.1,0.07),
(2 ,'dolor','sit',0.2,0.06),
(2 ,'amet','eos',0.3,0.05),
(3 ,'clita','corpora',0.5,0.04);
SELECT a.*
FROM my_table a
JOIN
( SELECT x.id
, x.value1
, MIN(x.value2) min_value2
FROM my_table x
JOIN
( SELECT id
, MIN(value1) min_value1
FROM my_table
GROUP
BY id
) y
ON y.id = x.id
AND y.min_value1 = x.value1
GROUP
BY x.id
, x.value1
) b
ON b.id = a.id
AND b.value1 = a.value1
AND b.min_value2 = a.value2;
+----+-------+---------+--------+--------+
| id | meta1 | meta2 | value1 | value2 |
+----+-------+---------+--------+--------+
| 1 | lorem | ipsum | 0.10 | 0.07 |
| 2 | dolor | sit | 0.20 | 0.06 |
| 3 | clita | corpora | 0.50 | 0.04 |
+----+-------+---------+--------+--------+
你可以无限期地扩展它,但在某些时候,替代解决方案可能变得更容易管理......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL
,meta1 VARCHAR(12)
,meta2 VARCHAR(12)
,value1 DECIMAL(5,2)
,value2 DECIMAL(5,2)
);
INSERT INTO my_table VALUES
(1 ,'foo' ,'bar' ,0.1,0.09),
(1 ,'baz' ,'quux' ,0.2,0.08),
(1 ,'lorem','ipsum' ,0.1,0.07),
(2 ,'dolor','sit' ,0.2,0.06),
(2 ,'amet' ,'eos' ,0.3,0.05),
(3 ,'clita','corpora',0.5,0.04),
(1 ,'bar' ,'foo' ,0.1,0.07);
SELECT a.*
FROM my_table a
JOIN
(
SELECT q.id
, q.value1
, q.value2
, MIN(q.meta1) min_meta1
FROM my_table q
JOIN
(
SELECT x.id
, x.value1
, MIN(x.value2) min_value2
FROM my_table x
JOIN
( SELECT id
, MIN(value1) min_value1
FROM my_table
GROUP
BY id
) y
ON y.id = x.id
AND y.min_value1 = x.value1
GROUP
BY x.id
, x.value1
) r
ON r.id = q.id
AND r.value1 = q.value1
AND r.min_value2 = q.value2
GROUP
BY q.id
, q.value1
, q.value2
) b
ON b.id = a.id
AND b.value1 = a.value1
AND b.value2 = a.value2
AND b.min_meta1 = a.meta1;
+----+-------+---------+--------+--------+
| id | meta1 | meta2 | value1 | value2 |
+----+-------+---------+--------+--------+
| 2 | dolor | sit | 0.20 | 0.06 |
| 3 | clita | corpora | 0.50 | 0.04 |
| 1 | bar | foo | 0.10 | 0.07 |
+----+-------+---------+--------+--------+