2019年3月29日金曜日

PHPでCSVを読み込んで、Arrayに変換するメソッド、最初の行を横方向連想配列のキーとするや、縦方向のid列を指定するや、一部の列のみ抽出するとか、機能盛りだくさん

/* $csvPath: CSV file path
  * $firstRowAsKey: whether make the first row as key horizontally. or just number, duplicate will not be over writed
  * $columnAsKey: whether to set key(column name or column index) column vertically. or just number, duplicate will not be over writed
  * $columnAsVal: Array or Single Column name or column index from 0, whether to filte columns
  * $smartFlat:if horizontally array only have one key, then falt it.
  *
  * For Example: CSV(this methord will take care of sjis utf8 encode problem)
  * name,point
  * Joe,2
  * Peter,321
  * Jane,34
  *
  * $firstRowAsKey = true, $columnAsKey = null, $columnsAsVal = null
  * Array([0] => Array([name] => Joe, [point] => 2), [1] => Array([name] => Peter,[point] => 321), [2] => Array([name] => Jane, [point] => 34))
  *
  * firstRowAsKey = false, $columnAsKey = 0, $columnsAsVal = null
  * Array([name] => Array([0] => name, [1] => point), [Joe] => Array([0] => Joe, [1] => 2), [Peter] => Array([0] => Peter, [1] => 321), [Jane] => Array([0] => Jane, [1] => 34))
  *
  * firstRowAsKey = true, $columnAsKey = 'name', $columnsAsVal = point
  * Array([Joe] => Array([point] => 2), [Peter] => Array([point] => 321), [Jane] => Array([point] => 34))
  */
 function readArrayCSV($csvPath, $firstRowAsKey = true, $columnAsKey = null, $columnsAsVal = null, $smartFlat = true) {
  $sjis = file_get_contents($csvPath);
  $utf8 = mb_convert_encoding($sjis, 'UTF-8', 'SJIS-win');
  $temp = tempnam(sys_get_temp_dir(), 'TMP_');
  file_put_contents($temp, $utf8);
  $csv = file($temp, FILE_IGNORE_NEW_LINES);

  if ($firstRowAsKey) {
   $titles = explode(",", array_shift($csv));
   $csv = array_map('str_getcsv', $csv);
   $csv = array_map(function ($row) use ($titles) {
       return array_combine($titles, $row);
   },$csv);
  } else {
   $csv = array_map('str_getcsv', $csv);
  }

  if ($columnAsKey !== null) {
   $result = array();
   if (is_int($columnAsKey) && $columnAsKey > 0) $columnAsKey--;
   foreach ($csv as $row) {
    if (isset($row[$columnAsKey])) {
     $row_filtered = $row;
     if ($columnsAsVal !== null) {
      $row_filtered = array_intersect_key($row, array_flip((array)$columnsAsVal));
     }
     $result[$row[$columnAsKey]] = ($smartFlat?(count($row_filtered) == 1?array_shift(array_values($row_filtered)):$row_filtered):$row_filtered);
    }
   }

  } else {
   $result = $csv;
  }
  return $result;
 }

2019年3月25日月曜日

mysql グループ毎、最初のレコードを取得 Select first recorder in every group

方法1:

SELECT * FROM
(
SELECT * FROM `table`
ORDER BY AnotherColumn
) t1
GROUP BY SomeColumn
;





方法2:

SELECT somecolumn, anothercolumn
FROM sometable
WHERE id IN (
SELECT min(id)
FROM sometable
GROUP BY somecolumn
);