[英]How to prevent duplicates on a foreach loop inside another foreach loop in PHP?
I have a music website where each time a user click on play, my PHP function insert into table views
我有一个音乐网站,每次用户单击播放时,我的PHP函数就会插入表格
views
I'm trying to reorder my MySQL database to optimize it in performance, so I tried in this example to count the total of views for each track
grouped by time. 我试图对MySQL数据库进行重新排序以优化其性能,因此在此示例中,我尝试按时间对每个
track
的视图总数进行计数。
Select only tracks that are in table views
: 仅选择表格
views
轨道:
$query = "SELECT `track` FROM `views` GROUP BY `track`";
The result for $query
: $query
的结果:
|track|
|-----|
|140 |
|125 |
|33 |
|... |
Count the number of rows for each result as plays and group by date: 计算每个结果作为播放的行数,并按日期分组:
$querysel = $this->db->query(sprintf("SELECT COUNT( * ) AS plays , `time`, `track` FROM `views` WHERE `track` = '%s' GROUP BY DATE( `time` )", $tid));
The result for $querysel
$querysel
的结果
|plays |time |track |
|------|--------------------|------|
|82 |2016-12-26 18:20:16 |140 |
|1 |2017-01-10 15:52:55 |140 |
|2 |2017-01-26 13:17:25 |140 |
Final insert in a new table the result: 最后在新表中插入结果:
$this->db->query(sprintf("INSERT INTO views_counts (tid,plays,time) VALUES ('%s','%s','%s')", $newtid, $plays, $time));
Here is my complete function: 这是我的完整功能:
function countViews() {
$query = "SELECT `track` FROM `views` GROUP BY `track`";
$result = $this->db->query($query);
while($row = $result->fetch_assoc()) {
$rows[] = $row;
}
foreach($rows as $row) {
$tid = $row['track'];
$querysel = $this->db->query(sprintf("SELECT COUNT( * ) AS plays , `time`, `track` FROM `views` WHERE `track` = '%s' GROUP BY DATE( `time` )", $tid));
while($rownew = $querysel->fetch_assoc()) {
$rowsnew[] = $rownew;
}
foreach($rowsnew as $rownew) {
$newtid = $rownew['track'];
$plays = $rownew['plays'];
$time = $rownew['time'];
$this->db->query(sprintf("INSERT INTO views_counts (tid,plays,time) VALUES ('%s','%s','%s')", $newtid, $plays, $time));
}
}
}
In my function I use GROUP BY DATE(
time )
,so why the final query insert into the new table views_counts
duplicates with the same time? 在我的函数中,我使用
GROUP BY DATE(
time )
,那么为什么最终查询同时插入到新表中views_counts
重复呢?
Here is my output : 这是我的输出 :
id | tid | plays | time
----|-----|-------|--------------
1 | 1 | 2 | 2017-01-26 12:43:16
2 | 1 | 1 | 2017-01-27 12:45:24
3 | 1 | 2 | 2017-01-26 12:43:16
4 | 1 | 1 | 2017-01-27 12:45:24
5 | 3 | 30 | 2016-12-26 18:20:16
6 | 1 | 2 | 2017-01-26 12:43:16
7 | 1 | 1 | 2017-01-27 12:45:24
8 | 1 | 2 | 2017-01-26 12:43:16
9 | 1 | 1 | 2017-01-27 12:45:24
10 | 3 | 30 | 2016-12-26 18:20:16
11 | 1 | 2 | 2017-01-26 12:43:16
12 | 1 | 1 | 2017-01-27 12:45:24
13 | 1 | 2 | 2017-01-26 12:43:16
14 | 1 | 1 | 2017-01-27 12:45:24
15 | 3 | 30 | 2016-12-26 18:20:16
As you see I have multiple same results for the same time. 如您所见,我同时具有多个相同的结果。
Here is what I expected: 这是我所期望的:
id | tid | plays | time
----|-----|-------|--------------
1 | 1 | 2 | 2017-01-26 12:43:16
2 | 1 | 1 | 2017-01-27 12:45:24
3 | 3 | 30 | 2016-12-26 18:20:16
UPDATE UPDATE
Here it is how I call this "one time" function: 这就是我所说的“一次”功能:
<?php
include("/var/www/html/includes/config.php");
include("/var/www/html/includes/classes.php");
session_start();
$db = new mysqli($CONF['host'], $CONF['user'], $CONF['pass'], $CONF['name']);
if ($db->connect_errno) {
echo "Failed to connect to MySQL: (" . $db->connect_errno . ") " . $db->connect_error;
}
$db->set_charset("utf8");
$feed = new feed();
$feed->db = $db;
$result = $feed->countViews();
mysqli_close($db);
?>
The function countViews()
is inside classes.php
. 函数
countViews()
在classes.php
。
I call this PHP just going to visit the requested page through the web. 我称此PHP仅用于通过Web访问请求的页面。
I would propose to solve your issue using just one query. 我建议仅使用一个查询来解决您的问题。
function countViews() {
$query = $this->db->query("SELECT COUNT( * ) AS plays , `time`, `track` FROM `views` GROUP BY `track`,DATE( `time` );");
while($row = $query->fetch_assoc()) {
$this->db->query(sprintf("INSERT INTO views_counts (tid,plays,time) VALUES ('%s','%s','%s')", $row['track'], $row['plays'], $row['time']));
}
}
Try this: 尝试这个:
function countViews() {
$query = "SELECT `track` FROM `views` GROUP BY `track`";
$result = $this->db->query($query);
while($row = $result->fetch_assoc()) {
$rows[] = $row;
}
$rowsnew = array();
foreach($rows as $row) {
$tid = $row['track'];
$querysel = $this->db->query(sprintf("SELECT COUNT( * ) AS plays , `time`, `track` FROM `views` WHERE `track` = '%s' GROUP BY DATE( `time` )", $tid));
while($rownew = $querysel->fetch_assoc()) {
$rowsnew[] = $rownew;
}
}
foreach($rowsnew as $rownew1) {
$newtid = $rownew1['track'];
$plays = $rownew1['plays'];
$time = $rownew1['time'];
$this->db->query(sprintf("INSERT INTO views_counts (tid,plays,time) VALUES ('%s','%s','%s')", $newtid, $plays, $time));
}
}
Can't it be done really in a single query? 真的不能在单个查询中完成吗?
INSERT INTO views_counts (tid, time, plays)
SELECT track, DATE(`time`), COUNT(*)
FROM `views`
GROUP BY track, DATE(`time`)
Note that the rows to INSERT
come from the SELECT
. 注意,
INSERT
的行来自SELECT
。
I took the liberty of using DATE(time)
, otherwise, which time
is picked is arbitrary. 我随意使用
DATE(time)
,否则,选择哪个 time
是任意的。
Ok, so only a single SELECT
query should suffice, which will be as follows: 好的,因此只有一个
SELECT
查询就足够了,如下所示:
$query = "SELECT `track`, `time`, COUNT(*) AS `plays` FROM `views`
GROUP BY `track`, DATE(`time`)
ORDER BY `track`, DATE(`time`);"
$result = $this->db->query($query);
while($row = $result->fetch_assoc()) {
$newtid = $row['track'];
$plays = $row['plays'];
$time = $row['time'];
$this->db->query(sprintf("INSERT INTO views_counts (tid,plays,time)
VALUES ('%s','%s','%s')",
$newtid, $plays, $time));
}
And that should ideally do the trick. 理想情况下,这应该可以解决问题。 A simple query demonstration using manually created sample data:
使用手动创建的示例数据的简单查询演示:
create table views (track int, `time` timestamp);
insert into views VALUES(1, '2017-01-26 12:43:16');
insert into views VALUES(1, '2017-01-27 12:45:24');
insert into views VALUES(1, '2017-01-27 12:50:30');
insert into views VALUES(2, '2017-01-25 01:00:00');
insert into views VALUES(2, '2017-01-25 02:00:00');
insert into views VALUES(2, '2017-01-26 11:30:00');
insert into views VALUES(2, '2017-01-26 11:45:00');
insert into views VALUES(2, '2017-01-26 13:45:00');
insert into views VALUES(2, '2017-01-26 15:45:00');
insert into views VALUES(2, '2017-01-27 08:00:00');
insert into views VALUES(3, '2017-01-27 09:00:00');
SELECT `track`, `time`, COUNT(*) AS plays FROM views
GROUP BY `track`, DATE(`time`) ORDER BY `track`, DATE(`time`);
Output produced using this query, which is what is expected to land in views_counts
: 使用此查询产生的输出,这将是在
views_counts
:
track | time | plays
----------------------------------------------
1 | 2017-01-26 12:43:16 | 1
1 | 2017-01-27 12:45:24 | 2
2 | 2017-01-25 01:00:00 | 2
2 | 2017-01-26 11:30:00 | 4
2 | 2017-01-27 08:00:00 | 1
3 | 2017-01-27 09:00:00 | 1
Hope that helps... 希望有帮助...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.