我需要做一组相当复杂的MySQL查询来生成适合于从分配给不同音乐艺术家的标签数据库中绘制D3的数据。相关表中的行(称为“lastfm_annotations”)为:user_id,artist_id,tag_id和tag_month(即,我们记录了特定用户在特定时间用特定标签标记特定艺术家的许多实例)。这全部嵌入在php脚本中。在一个复杂的MySQL查询中排序和分组
我最终需要生成的是一个JSON对象,该对象包含给定范围内的日期内该特定艺术家在该月内使用的每个唯一标记的次数(包括日期为零的计数。这是不使用给定的标签
这是我迄今为止(假设$ ITEMID和artist_id是可以互换位置):
$cal = array();
$result = mysql_query("select date from calendar;");
// this just gets all possible dates, but of course could be changed to get a different date range
if (!$result) {
echo 'Could not run query: ' . mysql_error();
exit;
}
for ($i = 0; $i < mysql_num_rows($result); $i++) {
$date =mysql_fetch_row($result)[0];
$result2 = mysql_query("select t2.tag_id, case when t1.freq is null then 0 else t1.freq end as freq from (select distinct tag_id from lastfm_annotations where artist_id='" . $itemID . "') t2 left join (select tag_id, count(*) as freq from lastfm_annotations where artist_id='" . $itemID . "' and tag_month='" . $date . "' group by tag_id) as t1 on t2.tag_id = t1.tag_id group by t2.tag_id");
$current = array();
$current['date'] = $date;
for ($j = 0; $j < mysql_num_rows($result2); $j++) {
$row = mysql_fetch_row($result2);
$tag = $row[0];
$freq = $row[1];
$result3 = mysql_query("select tag_name from lastfm_taglist where tag_id ='" . $tag . "' limit 1;");
$tagName = mysql_fetch_row($result3)[0];
$current[$tagName] = $freq;
}
array_push($data, $current);
}
echo json_encode($data);
(编辑:大查询如下)
select t2.tag_id
, case
when t1.freq is null then 0
else t1.freq
end as freq
from
(select distinct tag_id
from lastfm_annotations
where artist_id='$itemID') t2
left join
(select tag_id, count(*) as freq
from lastfm_annotations
where artist_id='$itemID'
and tag_month='$date'
group by tag_id) as t1
on t2.tag_id = t1.tag_id
group by t2.tag_id
(结束编辑)
这有效,但(至少)有两个大问题,我无法弄清楚。首先,在大丑SQL查询,我做多余的工作我每次经过循环时调用
(select distinct tag_id from lastfm_annotations where artist_id='" . $itemID . "')
,尽管该值每一次相同。任何想法我怎么能解决这个问题?也许可以以某种方式将唯一tag_ids保存为php数组,然后将其插入查询中?
其次,我需要确保标签始终按其总体频率排序(即跨越所有时间,而不仅仅是在特定月份内),但我不知道如何做到这一点。我可以使用查询像得到正确的顺序:
但我需要确保我的循环每个查询在相同的顺序返回标签。有任何想法吗?当我真正开始绘制数据时,也许最好在d3中处理排序,但是如果数据在进行SQL调用时以正确的顺序开始,那将会更好。
对不起,这个大问题,谢谢你的帮助!
感谢您编辑Alanyst - 现在它更具可读性。 – moustachio 2013-05-13 16:45:48
备注:可以使用更简洁的'ifnull(t1.freq,0)'代替查询中t1.freq为null,否则为其他t1.freq end'的情况。 – Alanyst 2013-05-13 17:01:59
如果艺术家A在特定的月份中使用了标签'foo',但从未用于艺术家B,艺术家B的结果应该具有标记'foo'的行(具有'freq' == 0),或者应该B的结果只有用于B的标签? – Alanyst 2013-05-13 17:18:14