如何根据计数或出现次数对同一mysql列中的值进行排序

时间:2016-07-16 14:14:32

标签: php mysql laravel-5 eloquent

我正在尝试按计数对laravel集合进行排序。 我有一个DB:USERS,在我的DB中有一个名为State的列,用于存储用户的主页状态示例:Florida

我把这个集合拉成这样的东西:

public function friends()
{
    return $this->friendsOfMine()
        ->wherePivot('accepted', true)
        ->get()
        ->merge(
            $this->friendsOf()
                ->wherePivot('accepted', true)
                ->get()
        );
}

然后在视图中:

@foreach ($user->friends() as $friend)
{{$friend->state}}
@endforeach

我希望按照从州的最大数量的朋友到州内最少量的朋友的顺序对状态进行排序并显示计数(该州的朋友总数)

示例:如果Newyork有100个朋友,Texas有70个朋友,佛罗里达有20个朋友,那么结果将是:

Newyork 100

德克萨斯州70

佛罗里达州20

我知道我可以使用count(),sort()和sortBy()等函数,但我不知道如何在这种情况下使用它,因为我在同一列中有值和想要根据状态出现的次数按count()对它们进行排序。

4 个答案:

答案 0 :(得分:2)

  

我想从最多的朋友那里按顺序排序状态   从州到最少数量的州和朋友显示计数   (该州的朋友总数)

// Get a collection of state names as keys
// and the frequency of each state as values,
// sorted by the frequency descending

$states_count = $user->friends->groupBy('state')->map(function ($states) {
    return $states->count();
})->sort()->reverse();

如果您希望朋友列表本身按州频率顺序排序,

// (If the states of any friends pair have equal frequency
// in the states list, sort those by state name alphabetically).

$friends_sorted = $user->friends->sort(function ($f1, $f2) use ($states_count) {
    if ($states_count->get($f1->state) < $states_count->get($f2->state)
      return 1;
    if ($states_count->get($f1->state) > $states_count->get($f2->state)
      return -1;

    return strcmp($f1->state, $f2->state);
});

答案 1 :(得分:0)

您可以在一个SQL查询中执行此操作:

SELECT state, friends, (SELECT SUM(friends) FROM friend_tbl) AS friend_total
FROM friend_tbl ORDER BY friends DESC

由于“friend_total”会被重复,所以看起来有点奇怪,但这只是一种方法。

STATE    |FRIENDS|FRIEND_TOTAL
new york |100    |190
texas    |70     |190
florida  |20     |190

答案 2 :(得分:0)

如果您想要&#34;在同一个mysql列&#34; 中对数据进行排序,您需要为创建一个查询中的TEMPORAL COLUMN 进行某种RAW查询>并使用它来制作计数器和排序数据(colTempName)

你需要做一些像:

SELECT col1,col2,state,count(*) AS colTempName
FROM [...]
( WHERE [...] / JOIN [...] )
GROUP BY columnbased_name_todo_count
ORDER BY colTempName,state

答案 3 :(得分:0)

您可能会遇到select中的选择问题,因为内部查询会针对每个外部记录再次触发。更好地规范化表并使用JOIN

考虑以下测试数据库(包括数据)

CREATE TABLE `state` (
  `state_id` int(11) NOT NULL,
  `name` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `state` (`state_id`, `name`) VALUES
(1, 'Florida'),
(2, 'California'),
(3, 'Wisconsin'),
(4, 'New Jersey');

CREATE TABLE `user` (
  `user_id` int(11) NOT NULL,
  `state_id` int(11) NOT NULL,
  `name` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `user` (`user_id`, `state_id`, `name`) VALUES
(1, 1, 'Person 1'),
(2, 2, 'Person 2'),
(3, 1, 'Person 3'),
(4, 3, 'Person 4'),
(5, 1, 'Person 5'),
(6, 1, 'Person 6'),
(7, 1, 'Person 7'),
(8, 3, 'Person 8');

CREATE TABLE `user_friend` (
  `user_id` int(11) NOT NULL,
  `friend_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `user_friend` (`user_id`, `friend_id`) VALUES
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(1, 6),
(1, 7),
(1, 8),
(2, 1),
(2, 5),
(2, 7),
(2, 8);

ALTER TABLE `state`
  ADD PRIMARY KEY (`state_id`);

ALTER TABLE `user`
  ADD PRIMARY KEY (`user_id`);

ALTER TABLE `user_friend`
  ADD PRIMARY KEY (`user_id`,`friend_id`);

user_friend的“friend_id”连接回用户表(发送给另一个用户)。

我使用了来自4个不同州的8个人,只有2个人有朋友。大多数人住在佛罗里达州。

现在查询有朋友的人员名单,以及该州的朋友姓名和数量,按降序排序。

SELECT 
  u.name as username,
  s2.name as friend_state,
  count(s2.state_id) as friends
FROM 
  `user` u
INNER JOIN 
  user_friend uf on u.user_id = uf.user_id
INNER JOIN 
  user f on f.user_id = uf.friend_id 
INNER JOIN 
  state s2 on s2.state_id = f.state_id
GROUP BY uf.user_id, s2.state_id
ORDER BY count(s2.state_id) DESC


+----------+--------------+---------+
| username | friend_state | friends |
+----------+--------------+---------+
| Person 1 | Florida      | 4       |
| Person 1 | Wisconsin    | 2       |
| Person 1 | California   | 1       |
| Person 2 | Florida      | 3       |
| Person 2 | Wisconsin    | 1       |
+----------+--------------+---------+

感谢阅读;)