![](/img/trans.png)
[英]How can I rewrite my PHP & MySQL to group my HTML list by equal column values?
[英]How can I rewrite my sql query so that it returns the values in a specific format (using mysql or php)?
我有一個叫做number
的表:
number_id | number_name
1 aaaa
2 bbbb
3 cccc
4 dddd
5 eeee
6 ffff
(它只包含6個條目)
我還有一個叫做texts
的表格:
text_id | start_time | number_id | text_content
1 some date1 | 2 | blabla1
2 some date2 | 1 | blabla2
3 some date3 | 2 | blabla3
4 some date4 | 3 | blabla4
5 some date5 | 4 | blabla5
6 some date6 | 6 | blabla6
etc.
(它包含很多條目)。
現在,當我正在進行這樣的查詢時:
SELECT
*
FROM
(SELECT
DATEDIFF(now(),
start_time) AS days_ago,
number_id,
COUNT(text_id) AS num_texts
FROM
TEXTS
WHERE
start_time BETWEEN DATE_SUB(NOW(), INTERVAL 100 DAY) AND NOW()
GROUP BY
DATE(start_time),
number_id) AS temp
它使用number_id返回每個地方過去100天每天的文本數量。 結果如下:
當我將它編碼為json時,我得到:
[{"days_ago":"19","number_id":"1","num_texts":"179"},
{"days_ago":"19","number_id":"5","num_texts":"1"},
{"days_ago":"18","number_id":"1","num_texts":"61"},
{"days_ago":"18","number_id":"2","num_texts":"1"},
{"days_ago":"18","number_id":"5","num_texts":"1"},
{"days_ago":"18","number_id":"6","num_texts":"3"},
{"days_ago":"17","number_id":"3","num_texts":"1"},
{"days_ago":"8","number_id":"1","num_texts":"2"},
{"days_ago":"8","number_id":"2","num_texts":"2"},
{"days_ago":"7","number_id":"4","num_texts":"1"},
我想寫一個不同的查詢,或更改現有的查詢。 有沒有辦法編寫一個查詢,將以下列方式返回我的數據:
[{"days_ago": "7", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"},
{"days_ago": "6", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"},
{"days_ago": "5", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"},
{"days_ago": "4", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"},
{"days_ago": "3", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"},
{"days_ago": "2", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"},
{"days_ago": "1", "number_id" : "1", "num_texts" : "18", "number_id" : "2", "num_texts" : "12", "number_id" : "3", "num_texts" : "12" , ... , "number_id" : "6", "num_texts" : "1"}]
基本上每行應該有6個number_id
每一行的days_ago
和值num_texts
的信息。 我需要限制此查詢僅過去7天,所以我知道我可以在這里修改它:
BETWEEN DATE_SUB(NOW(), INTERVAL 100 DAY) AND NOW()
並將100改為7,但有可能以某種方式得到這種特定格式的其他信息嗎?
哦還有一件事 - 我正在從php調用這個查詢,所以如果它更容易在php中以某種方式解析它並作為json返回,這也是一個選項。
非常感謝任何提示家伙!
=========編輯:
正如@AlexBlex指出的那樣 - 我提出的json結構可能無效,因為有多次使用相同的鍵名。 為了幫助您更好地理解我的問題 - http://thevectorlab.net/flatlab/morris.html這里是morris js圖表的例子。 我希望在該示例中將圖表生成為名為Quarterly Apple iOS device unit sales
的圖表。 在水平線上我想要日期( days ago
),在垂直線上我需要num_texts。 我希望有6行,每行代表不同的number_id。
假設您的number
具有永遠不會改變的這6個固定值,則可以通過鏈接6個texts
表副本(或創建6個視圖)來實現。
但是如果你通過跟蹤days_ago
更改並添加新的JSON記錄來在php中執行它可能會更加清晰。 您還必須確保沒有number_id
被跳過,用於添加一個零值num_texts
任何跳過。
另外,示例偽代碼:
$days_ago=0;
while ([read_records]) {
if (record['days_ago']!=$days_ago {
$days_ago!=0 [Close line]
$days_ago=record['days_ago'];
[Add new line]
[Add days_ago field] }
[Add number_id and num_texts fields]
}
[Close line]
第二個編輯,視圖解決方案:
如果view_1
是我在下面描述的視圖並且view_2
是number_id
2
的視圖,你可以將它們鏈接如下:
SELECT view_1.days_ago, view_1.num_texts AS num_texts1, view_2.num_texts AS num_texts2
FROM view_1 INNER JOIN view_2 ON view_1.days_ago=view_2.days_ago
如果每個days_ago
所有number_id
都有條目,則此willo只能正常工作,否則您將只需創建days_ago
的視圖並使用LEFT / RIGHT聯接來加入number_id
視圖。
您可以使用數據透視表執行此操作:
SELECT
days_ago,
SUM(IF(number_id = 1, num_texts, 0)) as num_1_texts,
SUM(IF(number_id = 2, num_texts, 0)) as num_2_texts,
SUM(IF(number_id = 3, num_texts, 0)) as num_3_texts,
SUM(IF(number_id = 4, num_texts, 0)) as num_4_texts,
SUM(IF(number_id = 5, num_texts, 0)) as num_5_texts,
SUM(IF(number_id = 6, num_texts, 0)) as num_6_texts
FROM
(SELECT
DATEDIFF(now(),start_time) AS days_ago,
number_id,
COUNT(text_id) AS num_texts
FROM
TEXTS
WHERE
start_time BETWEEN DATE_SUB(NOW(), INTERVAL 100 DAY) AND NOW()
GROUP BY
DATE(start_time),
number_id)
GROUP BY days_ago;
如果數字量是任意的,您可以使用您正在使用的任何語言生成字段列表。
在PHP中:
$selectFields = '';
$numbers = 10;
$separator = ''
for($i=1; $i<=$numbers; $i++) {
$selectFields .= $separator . "SUM(IF(number_id = {$i}, num_texts, 0)) as num_{$i}_texts";
$separator = ',';
}
$query = "
SELECT
days_ago,
$selectFields
FROM
(SELECT
DATEDIFF(now(),start_time) AS days_ago,
number_id,
COUNT(text_id) AS num_texts
FROM
TEXTS
WHERE
start_time BETWEEN DATE_SUB(NOW(), INTERVAL 100 DAY) AND NOW()
GROUP BY
DATE(start_time),
number_id)
ORDER BY days_ago
GROUP BY days_ago;
";
當然有人指出,你的JSON中有重復的id,但它可以很容易地表示為:
[{days_ago: "1", numbers: [{"id" : "1", "num_texts" : "12"},...{"id": "n", "num_texts": "999"}],
{days_ago: "2", numbers: [{"id" : "1", "num_texts" : "12"},...{"id": "n", "num_texts": "999"}],
...
或者Morris.js期待的任何格式。 您可以在一個軸上使用日期,在另一個軸上使用num_texts。 您可能還需要處理特定日期沒有活動的情況。
這樣的事情怎么樣:
<?php
$query = "SELECT DATEDIFF(now(), start_time) AS days_ago, number_id, COUNT(text_id) AS num_texts
FROM TEXTS
WHERE start_time BETWEEN DATE_SUB(NOW(), INTERVAL 100 DAY) AND NOW()
GROUP BY DATE(start_time), number_id";
$stmt = $conn->prepare($query);
$stmt->execute();
// convert to 2D array
while ($result = $stmt->fetch(PDO::FETCH_ASSOC))
{
if (!isset($res_ar[$result['days_ago']]))
{
$res_ar[$result['days_ago']] = array_fill(1, 6, 0);
}
$res_ar[$result['days_ago']][$result['number_id']] = $result['num_texts'];
}
// fill-in empty rows
for ($x = 1; $x <= 7; $x++)
{
if (!array_key_exists($x, $res_ar))
{
$res_ar[$x] = array_fill(1, 6, 0);
}
}
// convert to nested arrays
foreach ($res_ar as $days_ago => $texts)
{
$res_out[$days_ago]['days_ago'] = $days_ago;
foreach ($texts as $id => $count)
{
$res_out[$days_ago]['counts'][$id]['number_id'] = $id;
$res_out[$days_ago]['counts'][$id]['num_texts'] = $count;
}
}
// convert nested PHP arrays to nested JSON object
$json = json_encode($res_out);
?>
我實際上沒有運行這個,所以我不保證bug,但它至少應該讓你開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.