在我的软件评级表上,我有4个字段。id自动递增rvid供应商id评级日期评级日期对实际数值评级进行评级
在过去的几个月里,我已经做了很多工作,但这次我被难住了,我无法在脑海中清晰地想象最好的方法。我想做的是找出供应商是否有3个低的"连续"评级。如果他们的最后三个评级是<3然后我想标记它们。
我已经玩了几个小时了,所以我想我会问(不是为了得到答案),但为了找到一些推动我前进的道路方向,我陷入了在这里绕圈思考的困境。
我尝试过GROUP BY和ORDER BY,但这些尝试都不顺利,所以我想知道这是否不是mysql的答案,而是php的答案。换句话说,也许我只需要利用我目前所拥有的,通过usort等转到php方面,然后用这种方式来做。
这是我到目前为止所拥有的,我一开始也选择了id,认为这是获得最后一个结果的最佳方式,但后来我有了一个小突破,如果他们连续有3个,id就无关紧要了,所以我把它从查询中删除了。
$sql = "SELECT `rvid`, `rating` FROM `vendor_ratings_archive` WHERE `rating` <= '3' ORDER BY `rvid` DESC";
给我这个
Array
(
[0] => Array
(
[rvid] => 7
[rating] => 2
)
[1] => Array
(
[rvid] => 5
[rating] => 1
)
[2] => Array
(
[rvid] => 5
[rating] => 0
)
[3] => Array
(
[rvid] => 5
[rating] => 3
)
)
这只是我在田里扔的样品,这里只有4排,就像在现场一样,会有成吨的排。但基本上,这告诉我,这些供应商在表中的评分很低。这就是我被难住的地方。我只能在查询中做一个排序,所以这就是为什么我认为我需要接受这个并转移到php端来完成它
我想我需要先用php按rvid对元素进行排序,然后看看一行中的三个元素是否是同一个vender(rvid)。
希望这是有道理的。我的大脑很疼哈哈…
更新-这是使用*的所有表格数据
Array
(
[0] => Array
(
[id] => 7
[rvid] => 7
[ratedate] => 2016-05-01
[rating] => 2
)
[1] => Array
(
[id] => 8
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 1
)
[2] => Array
(
[id] => 6
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 0
)
[3] => Array
(
[id] => 5
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 3
)
)
这里有一种方法可以完全在SQL:中开始处理这个问题
- 获取供应商的最后评级。ORDER BY date DESC,限制1
- 获取供应商倒数第二的评级。ORDER BY date DESC,limit 1,OFFSET 1
然后编写一个查询,对前两个表进行LEFT联接。您将拥有一个包含三列的数据集:
- 供应商id
- 上次评级
- 倒数第二的评级
然后你可以写一个表达式,说"如果column1是<3,column2<三,那么这个新列是真的"
您应该能够相对容易地将其扩展到三列。
以下是a解决这个谜题的方法。我认为在这里解释它有帮助,亚历克斯也有帮助,因为他让我的大脑在使用日期。我首先开始考虑在查询中使用if语句,实际上这让我的大脑跳出了框框,然后我想到了该怎么办。
它并不完美,当然可以使用一些修剪来减少代码,但我理解它,它似乎有效,所以这对我来说是正常的。
查询。。。
$sql = "SELECT `rvid`, `ratedate`,`rating` FROM `vendor_ratings_archive` WHERE `rating` <= '3' ORDER BY `ratedate`, `rvid` DESC";
这给了我这个
Array
(
[0] => Array
(
[rvid] => 7
[ratedate] => 2016-05-01
[rating] => 2
)
[1] => Array
(
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 1
)
[2] => Array
(
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 0
)
[3] => Array
(
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 3
)
)
注意供应商(rvid)5是如何组合在一起的,这是一个额外的优势
接下来是一个简单的foreach来加载一个新的数组
foreach($results as $yield)
{
$rvidarray[] = $yield['rvid'];
}//close foreach
这给了我这个
阵列([0]=>7[1] =>5[2] =>5[3] =>5)
然后我们对数组值进行计数,以对重复进行分组
$rvidcounter = array_count_values($rvidarray);
这导致了
Array(
[7] => 1
[5] => 3
)
所以现在供应商7是1分低,供应商5是3分低,因为他们已经按日期排序了,我知道这是连续的。好吧,这听起来很好,哈哈")
然后我们用另一个foreach 创建我们的最终数组
foreach($rvidcounter as $key => $value)
{
//anything 3 or over is your watchlist
if($value > 2)
{
$watchlist[] = $key; //rvid number stored
}
}//close foreach
这给了我这个
Array
(
[0] => 5
)
这一切都是在服务功能中完成的。因此,最终的交易是,这个数组中的每个人都有超过3个连续的低评级,然后我只需在我的正常php进程文件中使用一个返回的数组,通过id获取每个供应商的名称,并将其传递到html并打印出列表。
完成。。。
如果你愿意,请随时改进。我可能会使用它,也可能不会使用它,因为上面的代码对我来说很有意义。从现在起6个月后,一些更复杂的东西对我来说可能没有意义。哈哈,但看看有人能想出什么来缩短这个过程会很有趣。
非常感谢和快乐编码
Dave:)
您可以在SQL中这样做:
SET @rvid = -1;
SELECT DISTINCT rvid FROM
(
SELECT
rvid,
@neg := rating<3, /* 0 or 1 for addition in next line */
@count := IF(@rvid <> rvid , @neg, @count+@neg) AS `count`, /* set or add */
@rvid := rvid /* remember last row */
FROM
testdb.venrate
ORDER BY
rvid, datetime desc
) subq
WHERE count>=3
;
您将一个变量设置为不存在的id。在每个按时间排序的行中,您检查评级是否过低,这会导致1(过低)或0(正常)。如果rvid不等于上一个rvid,则意味着新的供应商部分正在开始。在节的开头设置值0或1,否则添加此值。最后存储当前行的rvid,以便在下一行过程中进行比较。
上面的代码一直在寻找连续3个低评级(低表示小于3的值)。
一个小的修改检查最近的3个评级是否都等于或小于3:
SET @rvid = -1;
SELECT DISTINCT
rvid
FROM
(
SELECT
rvid,
@high_found := rating>3 OR (@rvid = rvid AND @high_found) unflag,
@count := IF(@rvid <> rvid , 1, @count+1) AS `count`,
@rvid := rvid /* remember last row */
FROM
testdb.venrate
ORDER BY
rvid, datetime desc
) subq
WHERE count=3 AND NOT unflag
;