伊莉討論區

標題: [已解決]從MySQL撈資料,遇中斷的日期後就沒資料了... [打印本頁]

作者: poxwu2002    時間: 2016-1-19 02:14 AM     標題: [已解決]從MySQL撈資料,遇中斷的日期後就沒資料了...

本帖最後由 poxwu2002 於 2016-1-19 10:52 PM 編輯

有一段資料,紀錄某人每個月的體重資料。資料庫裡的模擬資料如下:roweight
  u_serial
  [char]
  
  weight_day
  [date]
  
  Weight
  [decimal(4,1)]
  
  王小明
  
  2015-01-15
  
  80.0
  
  王小明
  
  2015-02-15
  
  86.3
  
  王小明
  
  2015-03-15
  
  88.0
  
  王小明
  
  2015-04-15
  
  87.6
  
  王小明
  
  2015-07-15
  
  86.5
  
  王小明
  
  2015-08-15
  
  84.6
  
  王小明
  
  2015-09-15
  
  80.6
  
  王小明
  
  2015-11-15
  
  79.9
  

如上表,小明5,6,10,12月忘了量體重,所以沒有資料...

我要用PHP撈資料,排成下面的格式:
  

Name/Month

  

1



2



3



4



5



6



7



8



9



10



11



12



王小明



80.0



86.3



88.0



87.6







86.5



84.6



80.6





79.9





我從資料庫撈資料、PHP顯示資料的片段:
  1. $sql = "SELECT `weight_day`, `weight` FROM `roweight` WHERE `u_serial`='王小明' AND YEAR(`weight_day`)='2015' AND MONTH(`weight_day`) BETWEEN 1 AND 12 ORDER BY `weight_day` ASC";
  2. $result = mysql_query($sql);
  3. $ad=0;
  4. while( $TempArray = mysql_fetch_row( $result )){
  5.   $data[$ad][0] = $TempArray[0];
  6.   $data[$ad][1] = $TempArray[1];
  7.   $ad++;
  8. };
  9. echo "<table width=\"100%\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">";
  10. echo "<thead>";
  11. echo "<tr><th>Name / Month</th>";
  12. for( $month=1; $month<=12; $month++ ){
  13.   echo "<th>{$month}</th>";
  14. };
  15. echo "</tr></thead>
  16. echo "<tbody><tr>";echo "<tr><th>王小明</th>";
  17. $ad=0;
  18. for( $month=1; $month<=12; $month++ ){
  19.   $rb_m = explode( "-", $data[$ad][0] ); //分解日期
  20.   $rb_m[1] = (int)$rb_m[1]; //去掉月份前導的0
  21.   if( $rb_m[1] == $month ){
  22.     echo "<th>".$data[$ad][1]."</th>";
  23.   }elseif( $rb_m[1] == "" ){
  24.     echo "<th>-</th>";
  25.   }else{
  26.   echo "<th>-</th>";
  27. };
  28. $ad++;
  29. };
  30. echo "</tr></tbody></table>";
複製代碼
很奇怪的是,顯示出來的資料,會變成這樣:
  Name/Month
  
  1
  
  2
  
  3
  
  4
  
  5
  
  6
  
  7
  
  8
  
  9
  
  10
  
  11
  
  12
  
  王小明
  
  80.0
  
  86.3
  
  88.0
  
  87.6
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  


我進資料庫,把三、四月的日期改成五、六月,也就是資料變成3,4,10,12月沒資料,可是出來的結果,會變成這樣:
  Name/Month
  
  1
  
  2
  
  3
  
  4
  
  5
  
  6
  
  7
  
  8
  
  9
  
  10
  
  11
  
  12
  
  王小明
  
  80.0
  
  86.3
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  
  ─
  


也就是說,資料會從沒有連續的月份開始斷了,消失了...
可是,我單獨 echo 日期、體重、data陣列甚至經過explode後的月份這些資料全都會正常顯示出來...如下表示:
  Name/Month
  
  1
  
  2
  
  3
  
  4
  
  5
  
  6
  
  7
  
  8
  
  9
  
  10
  
  11
  
  12
  
  陣列-日期
  
  2015-01-15
  
  2015-02-15
  
  2015-03-15
  
  2015-04-15
  
  2015-07-15
  
  2015-08-15
  
  2015-09-15
  
  2015-11-15
  
   
  
   
  
   
  
   
  
  Name/Month
  
  1
  
  2
  
  3
  
  4
  
  5
  
  6
  
  7
  
  8
  
  9
  
  10
  
  11
  
  12
  
  體重
  
  80.0
  
  86.3
  
  88.0
  
  87.6
  
  86.5
  
  84.6
  
  80.6
  
  79.9
  
   
  
   
  
   
  
   
  
  Name/Month
  
  1
  
  2
  
  3
  
  4
  
  5
  
  6
  
  7
  
  8
  
  9
  
  10
  
  11
  
  12
  
  月份
  
  1
  
  2
  
  3
  
  5
  
  7
  
  8
  
  9
  
  11
  
   
  
   
  
   
  
   
  


我的環境:
5.6.23-cll-lve - MySQL Community Server
PHP 版本: 5.3.29

困擾了好幾天的問題,請各位大大幫忙...

作者: sheauren    時間: 2016-1-19 08:35 AM

你資料庫出來的數量因為不是滿資料,
所以有些月份資料是空的
因此$month迴圈結束後$ad++應該會發生$ad超過$data陣列大小的錯誤,直接終止
比較簡單的做法是 你在db資料轉成陣列的時候 直接把weight_day整理成顯示要用的年月格式(此案例應該只要留下月)
下面$month迴圈 只要用array_key_exists去檢查是否有資料來顯示 保證只要跑12次可以顯示完成
作者: theloserbm    時間: 2016-1-19 11:13 AM

你的程式裡有邏輯上的錯誤

在你的月份迴圈是1, 2, 3, 4...這樣去跑
然後你檢查資料$ad 0, 1, 2 ,3...
如果0, 1, 2, 3的月份剛好對應1, 2, 3 ,4就可以正常顯示
如果月份是1, 2, 4, 5則1跟2會對上, 然後3!=4, 4!=5一直錯下去

單單要糾正這個邏輯錯誤要用的是內迴圈
  1. for ($month = 1; $month <= 12; $month++) {
  2.   $monthData = '-';
  3.   for ($ad = 0; $ad < $data.length; $ad++) {
  4.     if ($ad月份 == $month) {
  5.       $monthData = $data[$ad][1];
  6.     }
  7.   }

  8.   echo $monthData;
  9. }
複製代碼
雙迴圈有效能上的問題, 所以一般能避免的時候就應該避免. 如樓上所說有時候用key就可以繞過這個問題.

在讀入資料的時候, 建議把資料轉換為自己想要的格式
  1. while( $TempArray = mysql_fetch_row( $result )){
  2.   $rb_m = explode( "-", $TempArray[0] ); //分解日期
  3.   $rb_m = (int)$rb_m; //去掉月份前導的0
  4.   $data[$rb_m] = $TempArray[1];
  5. };
複製代碼
在這個時候$data的key就是月份
然後如樓上所說在下面迴圈就直接檢查有沒有這個key
  1. for( $month=1; $month<=12; $month++ ){
  2.   if(array_key_exists($month, $data) ){
  3.     echo "<th>".$data[$month]."</th>";
  4.   else{
  5.     echo "<th>-</th>";
  6.   }
  7. }
複製代碼

作者: poxwu2002    時間: 2016-1-19 10:52 PM

原來有 array_key_exists 這個函數..
看樣子,要買本書來看了...
謝謝大大們的指導!

小弟問題解決了!!
作者: poxwu2002    時間: 2016-1-20 10:56 AM

你去官方網站查api比較實際 關鍵字下的好google也能夠找到.. 例如 php array exists 大概就撈出來了  
重點就是,不知道有這樣的函數可以用呀!! ^^ 阿不然,我覺得我還蠻會 google 的呢!!
所以我才說,應該找書來看... 至少知道作者心裡 "常用的函數" 是哪些....XD


作者: sheauren    時間: 2016-1-21 08:33 AM

poxwu2002 發表於 2016-1-20 10:56 AM
重點就是,不知道有這樣的函數可以用呀!! ^^ 阿不然,我覺得我還蠻會 google 的呢!!
所以我才說,應該找書 ...

其實我也不知道函數是這名稱XD
因為其他語言有這功能
所以我才google看看這功能php是什麼
如果是要認真知道有那些api的話 書本還是不怎麼夠
直接去看官方document才會知道
書本只會寫一些常用的function或object
官方document其實分類的很詳細了,如果英文看得太吃力可以考慮看簡體版[瀏覽器也可以裝簡體轉繁體]
以string相關的功能來說,官法直接是一個大分類再解釋相關function,那一大排都可以寫一本書了
http://php.net/manual/en/ref.strings.php
作者: hsw1976    時間: 2016-3-19 04:13 AM

本帖最後由 hsw1976 於 2017-4-16 03:04 PM 編輯
poxwu2002 發表於 2016-1-20 10:56 AM
重點就是,不知道有這樣的函數可以用呀!! ^^ 阿不然,我覺得我還蠻會 google 的呢!!
所以我才說,應該找書 ...

不好意思,老人家又出來發發牢騷

說真的,不是很理解你們年輕一輩的 Programmer 是怎麼想的
你所提的狀況,一點都不是問題
不知道有這樣的函數可用,但你的需求卻是存在的
只能告訴你,根據需求善用官方手冊、搜尋引擎

吃程式設計這行飯,沒別的
幾乎都是找資料、學習消化資料、整合資料在交替進行

有空的時候,不妨多翻翻官方的函式手冊
當然不是要你背下來,而是走馬看花
知道大概有哪些東西就行

至少這樣的準備動作,就能避免掉大部份「不知道有這樣的函數可用」的奇怪情況
翻過手冊瞭解過大概,有需求時就能有個解決問題的方向
官方手冊如果確實沒有,再問問搜尋引擎
總會找到解決方式



作者: theloserbm    時間: 2016-3-21 11:28 AM

hsw1976 發表於 2016-3-19 04:13 AM
不好意思,老人家又出來發發牢騷

說真的,不是很理解你們年輕一輩的 Programmer 是怎麼想的

其實這也有關係到經驗和一點直覺
做久了就會大概知道, 我要的功能應該有內建函數能解決
或是類似這功能但是稍微不同條件
那google的命中率就會比較高

其實說白了, 世界那麼大, 我遇到的問題, 99%別人也遇到過並且發問和解決了
我只要找到那個紀錄(很大機會在stack overflow)就可以了
作者: chevylin0802    時間: 2016-3-21 11:41 AM

本帖最後由 chevylin0802 於 2016-3-21 11:53 AM 編輯
hsw1976 發表於 2016-3-19 04:13 AM
不好意思,老人家又出來發發牢騷

說真的,不是很理解你們年輕一輩的 Programmer 是怎麼想的

你沒發現他就只會使用for迴圈嗎?
連while() { }或者是do{ } while()都不會

這還是其次
另一個問題是出在於他只會直觀的寫作
並沒有發現到他寫程式時的盲點
也就是不懂得做系統分析
所以也就常常出現這種狀況了

事實上你如果去看的話
這已經可以算是很普遍屬於35歲以下年輕程式設計師的共同問題了

而這真的要歸咎到九年義務教育的數理教學的問題
以前我們學數學的時候一個應用題可以想得出四五種不同的解法
現在的學生只能按照課本上唯一的解法來寫
難道其它不同的解法就不是解法嗎?

問題就出在連小學國中的應用題
只要不是按照老師教的方法的步驟去寫就給你打全錯
所以現在年輕人就只會單向式的去思考解法
而變成只有垂直式的思考卻完全沒有水平式的思考




作者: chevylin0802    時間: 2016-3-23 07:11 AM

theloserbm 發表於 2016-3-21 11:28 AM
其實這也有關係到經驗和一點直覺
做久了就會大概知道, 我要的功能應該有內建函數能解決
或是類似這功能但 ...

主要是google時所要用的關鍵字
我也常看公司的RD在使用搜尋的功能
但他們常常用的關鍵字用得不是很巧
許多人你讓他去google
他有時候未必能找得到
stack overflow上雖然有非常多的幫助
也常常不見得符合他們所要的東西

作者: hsw1976    時間: 2016-6-6 10:32 AM

chevylin0802 發表於 2016-3-23 07:11 AM
主要是google時所要用的關鍵字
我也常看公司的RD在使用搜尋的功能
但他們常常用的關鍵字用得不是很巧
stack overflow上雖然有非常多的幫助
也常常不見得符合他們所要的東西


其實不只是 stack overflow 如此
程式設計相關論壇應該都是如此

或者應該這麼說吧
個人認為心態還是很重要
在程式設計的領域,由其是牽涉到客製化的
就別過於奢望能找到真正現成的東西
能找到「具有參考價值」,或者「相似、極為相似」的案例
就該偷笑了

在大部份情況下找到的資源
真要納入自己的體系
很抱歉
還是得靠自己消化整合






歡迎光臨 伊莉討論區 (http://a401.file-static.com/) Powered by Discuz!