2017-06-12 40 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;