Mysql唯一值查询

Mysql唯一值查询,mysql,Mysql,我有一个带有名称-值对和附加属性的表。同一名称可以有多个值。如果发生这种情况,我希望返回具有更高属性值的行 表: ID | name | value | attribute 1 | set1 | 1 | 0 2 | set2 | 2 | 0 3 | set3 | 3 | 0 4 | set1 | 4 | 1 所需的查询结果: name | value set2 | 2 set3 | 3 set1 | 4 获得所需结果的最佳sql查询是什么?没有简单的方

我有一个带有名称-值对和附加属性的表。同一名称可以有多个值。如果发生这种情况,我希望返回具有更高属性值的行

表:

ID | name | value | attribute
1  | set1 | 1     | 0
2  | set2 | 2     | 0
3  | set3 | 3     | 0
4  | set1 | 4     | 1
所需的查询结果:

name | value
set2 | 2
set3 | 3
set1 | 4

获得所需结果的最佳sql查询是什么?

没有简单的方法可以做到这一点

select name,max(value)
from table
group by name
有人提出了类似的问题

编辑:这里有一个建议:

SELECT `name`,`value` FROM `mytable` ORDER BY `name`,`attribute` DESC
这并不是您所要求的,但它至少会首先为您提供更高的属性值,您可以忽略其余的属性值

再次编辑:另一个建议:

SELECT `name`,`value` FROM `mytable` ORDER BY `name`,`attribute` DESC
如果知道该值是正整数,则可以执行此操作。这很恶心,但会管用的

SELECT `name`,CAST (GROUP_CONCAT(`value` ORDER by `attribute` DESC) as UNSIGNED) FROM `mytable` GROUP BY `name`

要包含负整数,可以将UNSIGNED改为SIGNED。

可能需要对所有这些选项进行基准测试,这里是另一个选项

SELECT t1.name, t1.value
  FROM temp t1
 WHERE t1.attribute IN (
   SELECT MAX(t2.attribute)
     FROM temp t2
    WHERE t2.name = t1.name);
那么:

SELECT ID, name, value, attribute  
  FROM table A
 WHERE A.attribute = (SELECT MAX(B.attribute) FROM table B WHERE B.NAME = A.NAME);

编辑:似乎有人已经说过同样的话。

性能最好的查询如下:

select
 s.set_id,
 s.name as set_name,
 a.attrib_id,
 a.name as attrib_name,
 sav.value
from
 sets s
inner join set_attribute_values sav on 
  sav.set_id = s.set_id and sav.attrib_id = s.max_attrib_id
inner join attributes a on sav.attrib_id = a.attrib_id
order by
 s.set_id;

+--------+----------+-----------+-------------+-------+
| set_id | set_name | attrib_id | attrib_name | value |
+--------+----------+-----------+-------------+-------+
|      1 | set1     |         3 | attrib3     |    20 |
|      2 | set2     |         0 | attrib0     |    10 |
|      3 | set3     |         0 | attrib0     |    10 |
|      4 | set4     |         4 | attrib4     |    10 |
|      5 | set5     |         2 | attrib2     |    10 |
+--------+----------+-----------+-------------+-------+
显然,要想实现这一点,您还必须使设计正常化,并实现一个简单的触发器:

drop table if exists attributes;
create table attributes
(
attrib_id smallint unsigned not null primary key,
name varchar(255) unique not null
)
engine=innodb;

drop table if exists sets;
create table sets
(
set_id smallint unsigned not null auto_increment primary key,
name varchar(255) unique not null,
max_attrib_id smallint unsigned not null default 0,
key (max_attrib_id)
)
engine=innodb;

drop table if exists set_attribute_values;
create table set_attribute_values
(
set_id smallint unsigned not null,
attrib_id smallint unsigned not null,
value int unsigned not null default 0,
primary key (set_id, attrib_id)
)
engine=innodb;

delimiter #

create trigger set_attribute_values_before_ins_trig 
before insert on set_attribute_values
for each row
begin
  update sets set max_attrib_id = new.attrib_id 
    where set_id = new.set_id and max_attrib_id < new.attrib_id;
end#

delimiter ;

insert into attributes values (0,'attrib0'),(1,'attrib1'),(2,'attrib2'),(3,'attrib3'),(4,'attrib4');
insert into sets (name) values ('set1'),('set2'),('set3'),('set4'),('set5');

insert into set_attribute_values values
(1,0,10),(1,3,20),(1,1,30),
(2,0,10),
(3,0,10),
(4,4,10),(4,2,20),
(5,2,10);

此解决方案的性能可能最好:

Select ...
From Table As T
    Left Join Table As T2
        On T2.name = T.name
            And T2.attribute > T1.attribute
Where T2.ID Is Null
另一种可能表现不佳的解决方案需要根据您的数据进行评估:

Select ...
From Table As T
Where Not Exists    (
                    Select 1
                    From Table As T2
                    Where T2.name = T.name
                        And T2.attribute > T.attribute
                    )

没有对其进行基准测试,但以下是其可行性: TableName=temm

属性值最大的1行:

select t.name, t.value
from (
   select name, max(attribute) as maxattr
   from temm group by name
) as x inner join temm as t on t.name = x.name and t.attribute = x.maxattr;
具有最大属性值的前N行中的2行:

select name, value
from temm
where (
   select count(*) from temm as n
   where n.name = temm.name and n.attribute > temm.attribute
) < 1 ; /*  1 can be changed to 2,3,4 ..N  to get N rows */

属性值重要吗?是的,这是棘手的部分。我不是在寻找属性最高的行中的值。我认为它需要一个内部连接,但我不确定具体如何编写。领带呢?假设还有另一行:5,set1,5,1。应该返回第4行还是第5行?这不符合问题的要求。问题要求的行具有最高的“属性”,而不是最高的“值”。SQL标准不允许在选择列表中使用非聚合列(在这种情况下为值)。它可能看起来有效,但理论上MySQL可以随机返回任何值。我正要检查这个答案,因为我测试了它,它工作得很好,但现在我被awm的评论弄糊涂了。@awm group_concat是一个聚合函数,对吗?使用它进行一些简单的字符串操作以仅获取第一个值,应该使其符合标准。但现在我们正进入一个混乱的领域。e、 g.将第一个SELECT更改为选择名称、子字符串_indexgroup _concatvalue',',1作为值。+1这是一个效率相当低的查询,但到目前为止,这是唯一一个真正执行所问内容的答案。:D,我们可以建议他规范化表。请执行。如何规范化表,然后如何运行查询?此查询的副作用是,将返回具有相同名称和相同最高属性值的多行。可能是,也可能不是我想要的行为。我投票赞成这个答案,而其他人投票反对?!