查询中的查询计数行,以根据所选类别进行分数

时间:2010-01-06 21:43:16

标签: sql mysql

这种手动编码查询是否可以变为动态?

SELECT master.id,
(select count(0) as score1 from scores where scores.id = master.id AND scores.category = '1'),
(select count(0) as score2 from scores where scores.id = master.id AND scores.category = '2'),
(select count(0) as score3 from scores where scores.id = master.id AND scores.category = '3'),
( repeat for as many categories chosen by the current user )
score1+score2+score3 AS score FROM master ORDER BY score DESC LIMIT 1

我知道这种语法不正确。

我想要的效果取决于用户选择的类别,我想找到一个记录。每条记录都在另一张表中评分。

我希望能够在括号中重复查询次数,因为根据另一个ID在另一个数据库中找到了类别:

anotherid,category
1,1
1,2
1,3
2,2
2,3
3,1
3,2
3,3

因此,如果我将'1'传递给上面的查询,我希望它在结果类别1,2和3的括号中重复查询(因此三个查询导致三个分数加起来总计)。

我之前曾试过问过这个问题,但我觉得我过于复杂了!

更新

我刚刚提出了这个问题 - 我觉得它有效。有人看到任何明显的错误吗?

SELECT
users.id,
users.url,
(
SELECT SUM(scoretot.scr) FROM scoretot WHERE scoretot.id = users.id AND scoretot.category 
IN (
SELECT category FROM getprefs WHERE member = '2'
)
) AS score
FROM users
ORDER BY score DESC limit 1

将在Perl中的查询中动态创建值2(它将是当前用户的ID)。

我有两个VIEWS

create view getprefs select `prefs`.`category` AS `category`,`prefs`.`member` AS `member` from `prefs`

create view scoretot select count(`scores`.`ref`) AS `scr`,`scores`.`id` AS `id`,`scores`.`category` AS `category` from `scores` group by `scores`.`category`

三张桌子:

表用户:

id,url
1,www.test.com
2,www.test2.com
3,www.test3.com

表分数:

id,category
1,1
1,1
1,2
1,2
1,3
1,3
1,3
2,2
3,1
3,3
3,3
3,3
3,2

表首选项

member,category
1,1
1,2
1,3
2,1
3,1
3,3

“认为”就是这样......

2 个答案:

答案 0 :(得分:0)

是的,基本上你想编码一个数据透视表。 首先,更简单的方法是使用更少的打字和更少的开销来实现:

SELECT    master.id
,         SUM(IF(s.category='1',1,0))   cat1
,         SUM(IF(s.category='2',1,0))   cat2
,         SUM(1)                        total
FROM      master m
LEFT JOIN scores s
ON        m.id = s.id
GROUP BY  master.id

(这是一个exaplanation和背景:http://rpbouman.blogspot.com/2005/10/creating-crosstabs-in-mysql.html

技巧当然是动态生成列。事实证明,您可以使用存储过程执行此操作。这是一个如何做到这一点的例子: http://www.futhark.ch/mysql/106.html

如果您使用的是MySQL代理,您还可以查看http://forge.mysql.com/wiki/ProxyCookbook

答案 1 :(得分:0)

为了更好的可读性,我建议您为子查询创建单独的views

CREATE VIEW v_scores_category1 AS 
    SELECT count(0) AS score1
    FROM scores where scores.id = mASter.id AND scores.category = '1'

CREATE VIEW v_scores_category2 AS
    SELECT count(0) AS score2
    FROM scores where scores.id = id AND scores.category = '2'

然后......

SELECT mASter.id,
(SELECT score1 FROM v_scores_category1),
(SELECT score2 FROM v_scores_category2),
score1+score2 AS score FROM mASter ORDER BY score DESC LIMIT 1

BTW:我知道这种语法不正确;)...