如何选择性地订购选定的行

时间:2017-02-01 08:22:53

标签: mysql sql sql-order-by

这是我的问题:

SELECT
  pr1.id AS user_id,
  pr1.title AS user_name,
  pr2.id AS liker_id,
  pr2.title AS liker_name,
  x.which AS which_table,
  x.cnt AS total
FROM 
(
  SELECT rid, rootid, which, COUNT(*) AS cnt
  FROM
  (
    SELECT rid, rootid, 'vote' which FROM p_likes
    UNION ALL 
    SELECT rid, rootid, 'comment' which FROM p_comments
    UNION ALL 
    SELECT rid, rootid, 'friend' which FROM relations
  ) y
  WHERE y.rootid = 1246 AND y.rootid <> y.rid
  GROUP BY y.rid, y.rootid, y.which
) x
INNER JOIN pagesroot pr1 on x.rootid = pr1.id
INNER JOIN pagesroot pr2 on x.rid = pr2.id
ORDER BY x.cnt desc;

以上是以下查询的输出//表示该记录的值与此问题无关。) < / p>

+---------+-----------+----------+------------+-------------+-------+
| user_id | user_name | liker_id | liker_name | which_table | total |
+---------+-----------+----------+------------+-------------+-------+
| //      | //        | //       | //         | vote        | 7     |
| //      | //        | //       | //         | vote        | 5     |
| //      | //        | //       | //         | vote        | 3     |
| //      | //        | //       | //         | comment     | 3     |
| //      | //        | //       | //         | vote        | 2     |
| //      | //        | //       | //         | comment     | 2     |
| //      | //        | //       | //         | comment     | 2     |
| //      | //        | //       | //         | vote        | 1     |
| //      | //        | //       | //         | vote        | 1     |
| //      | //        | //       | //         | vote        | 1     |
| //      | //        | //       | //         | comment     | 1     |
| //      | //        | //       | //         | friend      | 1     |
+---------+-----------+----------+------------+-------------+-------+

我试图做的就是交替排序行。如您所见,目前我根据total列对结果进行了排序。虽然我需要根据totalwhich_table对它们进行排序。这样的事情:(预期输出)

+---------+-----------+----------+------------+-------------+-------+
| user_id | user_name | liker_id | liker_name | which_table | total |
+---------+-----------+----------+------------+-------------+-------+
| //      | //        | //       | //         | vote        | 7     |
| //      | //        | //       | //         | comment     | 3     |
| //      | //        | //       | //         | friend      | 1     |
| //      | //        | //       | //         | vote        | 5     |
| //      | //        | //       | //         | comment     | 2     |
| //      | //        | //       | //         | vote        | 3     |
| //      | //        | //       | //         | comment     | 2     |
| //      | //        | //       | //         | vote        | 2     |
| //      | //        | //       | //         | comment     | 1     |
| //      | //        | //       | //         | vote        | 1     |
| //      | //        | //       | //         | vote        | 1     |
| //      | //        | //       | //         | vote        | 1     |
+---------+-----------+----------+------------+-------------+-------+

我该怎么做?

3 个答案:

答案 0 :(得分:0)

请尝试以下查询。使用ROW_NUMBER() OVER(PARTITION BY ..)为每个'which'项生成排名/记录号,并根据此进行排序。 (希望这对你有用,我没有表格模式或样本数据脚本来试试自己)

SELECT
  pr1.id AS user_id,
  pr1.title AS user_name,
  pr2.id AS liker_id,
  pr2.title AS liker_name,
  x.which AS which_table,
  x.cnt AS total
FROM 
(
  SELECT rid, rootid, which, COUNT(*) AS cnt
        ,ROW_NUMBER() OVER(PARTITION  BY which ORDER BY rid) AS new_order
  FROM
  (
    SELECT rid, rootid, 'vote' which FROM p_likes
    UNION ALL 
    SELECT rid, rootid, 'comment' which FROM p_comments
    UNION ALL 
    SELECT rid, rootid, 'friend' which FROM relations
  ) y
  WHERE y.rootid = 1246 AND y.rootid <> y.rid
  GROUP BY y.rid, y.rootid, y.which
) x
INNER JOIN pagesroot pr1 on x.rootid = pr1.id
INNER JOIN pagesroot pr2 on x.rid = pr2.id
ORDER BY new_order,x.cnt desc;

答案 1 :(得分:0)

我认为这并不是那么困难 - 我的模型在本质上与问题没有区别,我使用相关的子查询来分配投票(在我的模型中直播)总数为id的所有内容< / p>

MariaDB [sandbox]> select * from onetime_contest;
+------+-----------+------------+
| id   | status    | valid_till |
+------+-----------+------------+
|    1 | live      | 2017-01-01 |
|    2 | waiting   | 2017-01-01 |
|    3 | completed | 2017-01-01 |
|    4 | Waiting   | 2017-01-01 |
|    5 | live      | 2017-06-01 |
|    6 | waiting   | 2017-06-01 |
|    7 | completed | 2017-06-01 |
|    8 | Waiting   | 2017-06-01 |
|    1 | Live      | 2017-01-01 |
|    2 | Live      | 2017-01-01 |
|    3 | Live      | 2017-01-01 |
|    3 | Waitng    | 2017-01-01 |
|    4 | Live      | 2017-01-01 |
|    6 | Live      | 2017-01-01 |
|    7 | Live      | 2017-01-01 |
|    8 | Live      | 2017-01-01 |
|    1 | Waiting   | 2017-01-01 |
|    2 | Waiting   | 2017-01-01 |
|    2 | Live      | 2017-01-01 |
|    2 | Waiting   | 2017-01-01 |
|    2 | Live      | 2017-01-01 |
|    2 | Live      | 2017-01-01 |
+------+-----------+------------+
22 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]> select * from
    -> (
    -> select id, status ,count(*) as t1 ,count(*) as t2 from onetime_contest o1 where status = 'Live' group by id,status
    -> union
    -> select id, status ,count(*) as t1 ,(select count(*) from onetime_contest o2 where status = 'Live' and o2.id = o1.id  group by o2.id,o2.status)
    ->   from onetime_contest o1 where status = 'Waiting' group by id,status
    -> union
    -> select id, status ,count(*) as t1 ,(select count(*) from onetime_contest o2 where status = 'Live' and o2.id = o1.id  group by o2.id,o2.status)
    ->  from onetime_contest o1 where status = 'Completed' group by id,status
    -> ) s
    -> order by s.t2 desc,s.id,
    -> case when s.status = 'Live' then 1
    ->  when s.status = 'Waiting' then 2
    -> else 3 end;
+------+-----------+----+------+
| id   | status    | t1 | t2   |
+------+-----------+----+------+
|    2 | Live      |  4 |    4 |
|    2 | waiting   |  3 |    4 |
|    1 | live      |  2 |    2 |
|    1 | Waiting   |  1 |    2 |
|    3 | Live      |  1 |    1 |
|    3 | completed |  1 |    1 |
|    4 | Live      |  1 |    1 |
|    4 | Waiting   |  1 |    1 |
|    5 | live      |  1 |    1 |
|    6 | Live      |  1 |    1 |
|    6 | waiting   |  1 |    1 |
|    7 | Live      |  1 |    1 |
|    7 | completed |  1 |    1 |
|    8 | Live      |  1 |    1 |
|    8 | Waiting   |  1 |    1 |
+------+-----------+----+------+
15 rows in set (0.00 sec)

答案 2 :(得分:-1)

如果我理解你的问题,你可以使用:

SELECT function sum(array $input) { #Base case if ( count($input) == 0 ) { return; } if ( is_array( $input[0] ) ) { return $input[0][0] + sum( array_merge_recursive( array_slice($input, 1), array_slice($input[0], 1) ) ); } else { return $input[0] + sum( array_slice( $input, 1) ); } } print sum([10, 20, 30]); //60 print sum([10, [10,10], [20,10]]); //60

这些数字代表您的专栏。因此,如果要根据total和which_table对它们进行排序,可以编写:SELECT(您的代码)顺序为5,6