2017-06-12 78 views
1

我有一些数据如下表:SQL选择寻找其他的记录更好的价值

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 


CREATE TABLE `activities` (
    `id` int(10) UNSIGNED NOT NULL, 
    `project_id` int(10) UNSIGNED NOT NULL, 
    `user_id` int(10) UNSIGNED NOT NULL, 
    `task_hour` double(8,2) NOT NULL, 
    `validated` tinyint(1) NOT NULL DEFAULT '0' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 


INSERT INTO `activities` (`id`, `project_id`, `user_id`, `task_hour`, `validated`) VALUES 
(1, 1, 1, 10.00, 1), 
(2, 1, 1, 20.00, 0), 
(3, 2, 1, 5.00, 1), 
(4, 3, 1, 30.00, 0); 

当我做一个SELECT user_id,project_id,task_hour,validated FROM activities,这里是我得到:

| user_id | project_id | task_hour | validated | 
|---------|------------|-----------|-----------| 
|  1 |   1 |  10 |  true | 
|  1 |   1 |  20 |  false | 
|  1 |   2 |   5 |  true | 
|  1 |   3 |  30 |  false | 

我想从选择中得到如下结果:

| user_id | task_hour_total | 
|---------|-----------------| 
|  1 |    45 | 

这个结果来自task_hou r用于用户1,条件是只有在验证结果为true时才可以添加task_hour,或者如果验证为false,那么在表中没有相同user_id和project_id的记录且验证结果为true。

所以每行的理由是:

| user_id | project_id | task_hour | validated | 
|---------|------------|-----------|-----------| 
|  1 |   1 |  10 |  true | -> include in the sum because validated is true 
|  1 |   1 |  20 |  false | -> do not include in the sum because validated is false and there is the first record which has same user_id, same project_id and validated is true 
|  1 |   2 |   5 |  true | -> include in the sum because validated is true 
|  1 |   3 |  30 |  false | -> include in the sum because validated is false and there is no record in this table for user_id 1 and project_id 3 where validated is true 

我曾尝试以下,但它告诉我,这是不是在MySQL中右结构。这是第一个测试,以取得柱说,如果它发现在DB的另一个纪录,验证= TRUE为同一USER_ID和PROJECT_ID:

select @u = user_id, @p = project_id,task_hour,validated 
case when (select count(*) from activities where user_id = @u and project_id = @p and validated = true) > 1 then 'validated found' end as found 
from activities 

谢谢你,如果你能帮助我在这一个...

+1

什么是“不工作”的定义?任何错误?意外的输出?您使用共享的示例数据获得的输出是什么?在示例数据中,项目C未经过验证,但您仍在为其添加30个小时。是错字还是故意?如果有意识的话那么它是如何不同的,那么项目A小时20小时也是没有验证的? –

+0

什么是你想从源表返回的字段? – Alexander

+0

请参阅https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple-sql-查询 – Strawberry

回答

1

在标准SQL中,您可以使用ROW_NUMBER对记录进行排名,但MySQL不支持该标准功能。排名很简单:每user_idproject_id你想要更好的记录。更好的意思是validated真是比错误更好。

在MySQL中,true为1,false为0.因此,您希望每个user_idproject_id的最大值为validated。您可以使用IN子句来实现此目的。

select user_id, sum(task_hour) as task_hour_total 
from activities 
where (user_id, project_id, validated) in 
(
    select user_id, project_id, max(validated) 
    from activities 
    group by user_id, project_id 
) 
group by user_id; 

还是一个简单的查询。与ROW_NUMBER方法的区别在于记录必须被读取两次。

0

好的,我找到了一个方法来做到这一点。这是不是很优雅,但它的工作原理:

SELECT user_id,sum(task_hour) 
FROM 
(SELECT * FROM activities a1 WHERE a1.project_id NOT IN (SELECT project_id FROM activities as a2 WHERE validated = 1) 
UNION SELECT * FROM activities WHERE validated = 1) 
AS temp_table 
GROUP BY user_id 

如果有人知道比这更好的解决办法,否则不犹豫,我将留在这个漫长而复杂的选择。

0

我发现编写下一个查询很简单。我希望它能帮助你。

SELECT user_id, 
     SUM(task_hour) 
    FROM activities 
WHERE validated = 1 
    OR project_id NOT IN (SELECT project_id 
          FROM activities 
          WHERE validated = 1) 
GROUP BY user_id; 
相关问题