我正在try 编写一个SQL查询来显示课程的受欢迎程度,

  • 课程受欢迎程度以分数衡量,其确定如下:For every survey:
  • a、 如果票数不同>10%的总票数,受欢迎程度较高的课程得1分,受欢迎程度较低的课程得0分
  • b、 如果票数不同<=总票数的10%,每门课程获得0.5票
course_id course_name faculty
1001 economics_101 business
1002 algebra_101 math
1003 geometry_101 math
1004 management_101 business
1005 marketing_101 business
1006 physics_101 science
survey_id option_a option_b votes_a votes_b
2001 economics_101 geometry_101 61 34
2002 algebra_101 economics_101 31 68
2003 marketing_101 management_101 11 72
2005 management_101 algebra_101 43 54
2004 geometry_101 marketing_101 48 46

迄今取得的成果:

course popularity
economics_101 4
management_101 2
algebra_101 2
marketing_101 1
geometry_101 1
[NULL] 0

到目前为止,我成功地加入了它,如果能为优化这个查询提供帮助,那就太好了:

    WITH x AS 
(
WITH b AS 

(

WITH a as 
(
select * from course c
LEFT  JOIN survey s
on c.course_name = s.option_a 

UNION ALL 

select * from course c
LEFT  JOIN survey s
on c.course_name = s.option_b
)

SELECT a.*,
SUM(votes_a+votes_b) as total_votes,
CASE WHEN (a.votes_a - a.votes_b) > (0.1*SUM(votes_a+votes_b))  THEN 1 
     WHEN (a.votes_b - a.votes_a) <= (0.1*SUM(votes_a+votes_b))  THEN 0.5
     ELSE 0
END AS 'Popularity_a',

CASE WHEN (a.votes_b - a.votes_a) > (0.1*SUM(votes_a+votes_b))  THEN 1 
     WHEN (a.votes_a - a.votes_b) <= (0.1*SUM(votes_a+votes_b))  THEN 0.5
     ELSE 0
END AS 'Popularity_b'


FROM 
a
GROUP BY 
a.course_name ,
a.course_id,
a.faculty ,
a.survey_id ,
a.option_a ,
a.option_b ,
a.votes_a ,
a.votes_b 
)

SELECT b.option_a  as course,
b.Popularity_a as pop
FROM b
LEFT JOIN 
course cx 
ON b.option_a  = cx.course_name  

UNION ALL 

SELECT b.option_b as course ,
b.Popularity_b as pop
FROM b
LEFT JOIN 
course cx 
ON b.option_b  = cx.course_name 
)

select
x.course ,
sum (x.pop) as popularity
from x
GROUP BY
x.course 

order by popularity desc

推荐答案

Use UNION ALL to extract all courses and the respective points they get from the table survey and aggregate to get the popularity.
Then join to course:

WITH 
  cte AS (
    SELECT option_a course_name, 
           CASE 
             WHEN votes_a - votes_b > 0.1 * (votes_a + votes_b) THEN 1.0 
             WHEN votes_b - votes_a > 0.1 * (votes_a + votes_b) THEN 0.0
             ELSE 0.5 
           END points
    FROM survey
    UNION ALL
    SELECT option_b, 
           CASE 
             WHEN votes_b - votes_a > 0.1 * (votes_a + votes_b) THEN 1.0 
             WHEN votes_a - votes_b > 0.1 * (votes_a + votes_b) THEN 0.0
             ELSE 0.5 
           END
    FROM survey
  ),
  points AS (
    SELECT course_name, SUM(points) total_points
    FROM cte
    GROUP BY course_name
  )
SELECT c.*, COALESCE(p.total_points, 0) popularity
FROM course c LEFT JOIN points p
ON p.course_name = c.course_name
ORDER BY popularity DESC;

See the demo.

Sql相关问答推荐

retrofit AWS Athena中的JSON

PostgreSQL中的合并命令是原子的,还是需要一些类似于SQL Server版本的内容?

如何更新SQLite数据库中的表?

如何查找所提供日期范围的所有季度开始日期和结束日期

在SQL中为两个日期之间的每个日期添加行

SQL Athena/prest判断值是否在嵌套的json数组中

使用特定的Order By子句随机化SQL输出

使用左外部联接更正列中第+1行的值时重复

具有分组条件的不同计数 (DAX)

将时间戳四舍五入到最近 10 分钟的查询

SQL 搜索 - 获取最大值日期的奇怪行为

如何使用 Google BigQuery 中的条件根据特定列值连接列的 N 行?

SQL 中的第一个值和倒数第二个值

根据开始时间和结束时间计算has_impact字段

根据行号将列转置为没有任何id或键列的行

T-SQL - 返回每条记录的最近雇佣日期

Select 给定类别列表(或更多类别)中的所有事物

如果当前日期是一周中的某一天,则从另一天提取结果

PostgreSQL Select 具有两列的自引用

如何在 SQL Server 中参数化 Select top 'n'