1

我的意思是说:

想象一下这些表:

Table article_status:             Table users:

userid  | article | status        id | name
--------+---------+-------        ---+------
 1      | 1       | 1              1 | Peter
 1      | 2       | 2              2 | Bob
 2      | 3       | 1
 2      | 4       | 1
 2      | 5       | 2
 2      | 6       | 2
 2      | 7       | 3

我想要得到的是按用户状态编号分组的所有项目的计数。可能的状态值的数量是已知的 (4)。

示例结果users.id = 2

userid | name | s1_count | s2_count | s3_count | s4_count |
-------+------+----------+----------+----------+----------+
 2     | Bob  | 2        | 2        | 1        | 0        |

我试过的:

SELECT 
  u.id AS userid
, u.name
, COUNT(s1.status) AS s1_count
, COUNT(s2.status) AS s2_count
, COUNT(s3.status) AS s3_count
, COUNT(s4.status) AS s4_count
FROM users AS u
INNER JOIN article_status AS s1 ON s1.userid = u.id AND s1.status = 1 
INNER JOIN article_status AS s2 ON s2.userid = u.id AND s2.status = 2 
INNER JOIN article_status AS s3 ON s3.userid = u.id AND s3.status = 3 
INNER JOIN article_status AS s4 ON s4.userid = u.id AND s4.status = 4 
WHERE u.id = :uid
LIMIT 1

但这不起作用(为什么?)而且看起来非常不理想。有任何想法吗?

4

3 回答 3

2

这被称为旋转您的数据...一种方法是使用CASE语句:

SELECT 
  u.id
, u.name
, COUNT(CASE WHEN a_s.status = 1 THEN 1 END) AS s1_count
, COUNT(CASE WHEN a_s.status = 2 THEN 1 END) AS s2_count
, COUNT(CASE WHEN a_s.status = 3 THEN 1 END) AS s3_count
, COUNT(CASE WHEN a_s.status = 4 THEN 1 END) AS s4_count
FROM users AS u
INNER JOIN article_status AS a_s ON a_s.userid = u.id 
WHERE u.id = :uid
GROUP BY u.id, u.name
LIMIT 1
于 2013-01-02T19:38:50.143 回答
1

您可以使用带有 a 的聚合函数CASE来获取结果:

SELECT 
  u.id,
  u.name,
  sum(CASE WHEN a.status = 1 THEN 1 else 0 END) s1_count,
  sum(CASE WHEN a.status = 2 THEN 1 else 0 END) s2_count,
  sum(CASE WHEN a.status = 3 THEN 1 else 0 END) s3_count,
  sum(CASE WHEN a.status = 4 THEN 1 else 0 END) s4_count
FROM users u
INNER JOIN article_status a 
  ON u.id = a.userid
GROUP BY u.id, u.name

请参阅带有演示的 SQL Fiddle

或者你可以使用很多子查询来返回数据:

select u.id,
  u.name,
  coalesce(s1_count, 0) s1_count,
  coalesce(s2_count, 0) s2_count,
  coalesce(s3_count, 0) s3_count,
  coalesce(s4_count, 0) s4_count
from users u
left join
(
  select count(*) s1_count, userid
  from article_status
  where status = 1
  group by userid
) s1
  on u.id = s1.userid
left join
(
  select count(*) s2_count, userid
  from article_status
  where status = 2
  group by userid
) s2
  on u.id = s2.userid
left join
(
  select count(*) s3_count, userid
  from article_status
  where status = 3
  group by userid
) s3
  on u.id = s3.userid
left join
(
  select count(*) s4_count, userid
  from article_status
  where status = 4
  group by userid
) s4
  on u.id = s4.userid

请参阅带有演示的 SQL Fiddle

于 2013-01-02T19:55:03.830 回答
0

不要做类似 COUNT(s1.status) 的事情,试试下面的

COUNT(DISTINCT(CONCAT(s1.article, '-', s1.status)))

这只是我的一个理论,因为它将明显依赖于状态和文章。告诉我它是否有效!

于 2013-01-02T19:36:29.703 回答