2014-02-19 232 views
1

请帮忙写一个将整理数据的SQL脚本。
一个关键的难点 - 需要创建一个额外的列进行排序。
我试图描述尽可能详细的情况。
带查询的SQL查询

让我们开始吧。有以下形式的表:
datas
我们会在收到用户ID和返回数据,只有那些没有谁他,但也有其他人。
下一步:按人工创建的列进行排序。

接下来,我会一步一步来。
那么我的意思是人为的列:
这一列将包含估计之间的差异。所以要得到它 - 您需要先执行一些操作:
根据设置用户和其他用户的信息来计算评估差异,并获得平均分数。
下面的两张图片显示了相同的数据,然后是计算本身,在我看来 - 这很简单。
enter image description here


计算此列如下:

User with 2nd id: 
1: 5 - 1 = 4; 
2: 2 - 9 = -7; 
3: next data what is in user 1 - absent in user 2, and we ease pass it; 
User with 3rd id: 
1: 3 - 1 = 2; 
2: the next data's is absent in user with 3rt id; 
3: 8 – 9 = -1; 
4: 6 – 2 = 4; 
5: passed; 

End in the end: 
User_2 will have new mark = -1.5 
User_3 will have new mark = 1.66666 

而在最后,我需要回到表: enter image description here
但是这还不是全部。通常情况下,数据将被复制,我希望从所获得的数据中获得平均结果。请看下面的例子:

enter image description here

这是结束。我真的需要你的帮助,专家。我自己教SQL代码,但这对我来说很困难。
有做脚本如下的想法:

SELECT d.data, (d.mark + myCount(d.user, 1)) newOrder 
FROM info d 
WHERE -- data from user_1 NOT equal data from other users 
ORDER BY newOrder; 

但脚本将执行大量的时间,因为它使用其自身的功能,可以用做查询到每个用户,而不是记录。我希望有人能够应付这个任务。

回答

1

追随你的步骤:

首先,我们需要将数据从选定的用户隔离(假设它是1):

CREATE TEMP TABLE sel_user AS 
SELECT data, mark FROM info d WHERE user = 1; 

现在,我们计算大关的用户有(再次,所选择的用户是1):

SELECT d.user user, d.mark - s.mark mark 
FROM info d JOIN sel_user s USING (data) 
WHERE d.user <> 1; 

结果:

user  mark  
---------- ---------- 
2   4   
2   -7   
3   2   
3   -1   
3   4   

我们可以查询只平均:

SELECT d.user user, AVG(d.mark - s.mark) mark 
FROM info d JOIN sel_user s USING (data) 
WHERE d.user <> 1 GROUP BY user; 

user  mark  
---------- ---------- 
2   -1.5  
3   1.66666666 

但你还是想这样做与不对应于用户1的标记算了一笔账:

SELECT d.user user, mark FROM info d 
WHERE d.user <> 1 AND d.data NOT IN (SELECT data FROM sel_user); 
user  mark  
---------- ---------- 
2   4   
3   3   
3   10 

具体来说,要添加先前计算平均每行:

SELECT d.user user, d.data, d.mark + d2.mark AS neworder FROM info d JOIN (
    SELECT d.user user, AVG(d.mark - s.mark) mark 
    FROM info d JOIN sel_user s USING (data) 
    WHERE d.user <> 1 GROUP BY user 
) d2 USING (user) 
WHERE d.data NOT IN (SELECT data FROM sel_user) 
ORDER BY neworder DESC; 
user  data  neworder   
---------- ---------- ---------------- 
3   6   11.6666666666667 
3   3   4.66666666666667 
2   5   2.5    

而且你的最后一个请求是让平均每个data

SELECT data, AVG(neworder) final FROM (
    SELECT d.user user, d.data, d.mark + d2.mark AS neworder FROM info d JOIN (
     SELECT d.user user, AVG(d.mark - s.mark) mark 
     FROM info d JOIN sel_user s USING (data) 
     WHERE d.user <> 1 GROUP BY user 
    ) d2 USING (user) 
    WHERE d.data NOT IN (SELECT data FROM sel_user) 
) 
GROUP BY data 
ORDER BY final DESC; 
data  final   
---------- ---------------- 
6   11.6666666666667 
3   4.66666666666667 
5   2.5  
+0

类似的方法来我的想法,但我正在做一个自我连接的原则。 – DRapp