#システム概要
csvで株価一覧をダウンロードしてくる(人が作業)
phpのページを使ってDBにインサートする
php別ページで条件に合う株銘柄があるかを検索したい
その際に検索条件が4日間"today_close "-"today_open ">0のものとしたい
この場合SQLで別テーブルに4日連続"today_close "-"today_open ">0であるかどうかをbooleanで入れておいて検索時にそちらを参照する形がいいと思っているのですがそれができずに困っています
php
1<?php 2/* HTML特殊文字をエスケープする関数 */ 3function h($str) { 4 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 5} 6$double_array = [6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,23,24]; 7// パラメータを正しい構造で受け取った時のみ実行 8if (isset($_FILES['upfile']['error']) && is_int($_FILES['upfile']['error'])) { 9 try { 10 /* ファイルアップロードエラーチェック */ 11 switch ($_FILES['upfile']['error']) { 12 case UPLOAD_ERR_OK: 13 // エラー無し 14 break; 15 case UPLOAD_ERR_NO_FILE: 16 // ファイル未選択 17 throw new RuntimeException('File is not selected'); 18 case UPLOAD_ERR_INI_SIZE: 19 case UPLOAD_ERR_FORM_SIZE: 20 // 許可サイズを超過 21 throw new RuntimeException('File is too large'); 22 default: 23 throw new RuntimeException('Unknown error'); 24 } 25 $tmp_name = $_FILES['upfile']['tmp_name']; 26 $detect_order = 'ASCII,JIS,UTF-8,CP51932,SJIS-win'; 27 setlocale(LC_ALL, 'ja_JP.UTF-8'); 28 /* 文字コードを変換してファイルを置換 */ 29 $buffer = file_get_contents($tmp_name); 30 if (!$encoding = mb_detect_encoding($buffer, $detect_order, true)) { 31 // 文字コードの自動判定に失敗 32 unset($buffer); 33 throw new RuntimeException('Character set detection failed'); 34 } 35 file_put_contents($tmp_name, mb_convert_encoding($buffer, 'UTF-8', $encoding)); 36 unset($buffer); 37 /* データベースに接続 */ 38 $pdo = new PDO( 39 'mysql:dbname=DB名;host=localhost;charset=UTF8', 40 'root', 41 '', 42 array( 43 // カラム型に合わない値がINSERTされようとしたときSQLエラーとする 44 PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION sql_mode='TRADITIONAL'", 45 // SQLエラー発生時にPDOExceptionをスローさせる 46 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 47 // プリペアドステートメントのエミュレーションを無効化する 48 PDO::ATTR_EMULATE_PREPARES => false, 49 ) 50 ); 51 52 $stmt = $pdo->prepare('INSERT INTO tableA VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); 53 /* トランザクション処理 */ 54 $pdo->beginTransaction(); 55 try { 56 $fp = fopen($tmp_name, 'rb'); 57 while (($row = fgetcsv($fp)) !== FALSE) { 58 if ($row === array(null)) { 59 // 空行はスキップ 60 continue; 61 } 62 //print_r($row[1]); 63 /*ここに"-"が格納されていた場合の処理を記載する*/ 64 for($i = 0; $i < 25; $i++){ 65 if(strcmp($row[$i],'-') == 0){ 66 //var_dump($row[1]); 67 $st = $pdo->prepare('SELECT * FROM tableA where SC = ? ORDER BY date DESC LIMIT 1'); 68 69 if($st->rowCount() === 0){ 70 if(in_array($i,$double_array)){ 71 $row[$i]=0; 72 //var_dump($row[$i]); 73 }else{ 74 $row[$i]=NULL; 75 //var_dump($row[$i]); 76 } 77 }else{ 78 while($ro = $st -> fetch(PDO::FETCH_ASSOC)){ 79 //一日前のデータを入れる 80 } 81 } 82 83 }else{ 84 //var_dump($row[$i]); 85 } 86 } 87 if (count($row) > 10000) { 88 // カラム数が異なる無効なフォーマット 89 throw new RuntimeException('Invalid column detected'); 90 } 91 $executed = $stmt->execute($row); 92 } 93 if (!feof($fp)) { 94 // ファイルポインタが終端に達していなければエラー 95 throw new RuntimeException('CSV parsing error'); 96 } 97 fclose($fp); 98 $pdo->commit(); 99 } catch (Exception $e) { 100 fclose($fp); 101 $pdo->rollBack(); 102 throw $e; 103 } 104 /* 結果メッセージをセット */ 105 if (isset($executed)) { 106 // 1回以上実行された 107 $msg = array('green', 'Import successful'); 108 } else { 109 // 1回も実行されなかった 110 $msg = array('black', 'There were nothing to import'); 111 } 112 } catch (Exception $e) { 113 /* エラーメッセージをセット */ 114 $msg = array('red', $e->getMessage()); 115 } 116} 117// XHTMLとしてブラウザに認識させる 118// (IE8以下はサポート対象外w) 119header('Content-Type: application/xhtml+xml; charset=utf-8'); 120?> 121<!DOCTYPE html> 122<html xmlns="http://www.w3.org/1999/xhtml"> 123<head> 124 <title>CSV to MySQL importation test</title> 125</head> 126<body> 127<?php if (isset($msg)): ?> 128 <fieldset> 129 <legend>Result</legend> 130 <span style="color:<?=h($msg[0])?>;"><?=h($msg[1])?></span> 131 </fieldset> 132<?php endif; ?> 133 <form enctype="multipart/form-data" method="post" action=""> 134 <fieldset> 135 <legend>Select File</legend> 136 Filename(CSV is only supported): <input type="file" name="upfile" /><br /> 137 <input type="submit" value="Upload" /> 138 </fieldset> 139 </form> 140</body> 141</html>
MySQL
1CREATE TABLE tableA( 2 SC int(4) NOT NULL "証券コード", 3 name varchar(32) NOT NULL "会社名", 4 market varchar(16) NOT NULL "市場", 5 industry varchar(16) NOT NULL "産業", 6 date datetime NOT NULL "日にち", 7 today_close double "当日終値", 8 the_day_before_ratio double "前日との幅", 9 the_day_before_ratio_per double "前日幅%", 10 ago_close double "前日終値", 11 today_open double "始値", 12 today_high double "高値", 13 today_low double "安値", 14 vwap double "vwap", 15 volume double "出来高", 16 volume_per double "出来高%", 17 trading_value double "売買代金", 18 market_capitalization double "時価総額", 19 price_range_low_limit double "値幅下限", 20 price_range_high_limit double "値幅上限", 21 high_date datetime "高値日", 22 year_to_date_high_price double "年初来高値", 23 year_to_date_high_price_deviation_rate double "年初来高値乖離", 24 low_date datetime "安値日", 25 year_to_date_low_price double "年初来安値", 26 year_to_date_low_price_deviation_rate double "年初来安値乖離" 27);
##やったこと
mySQL
1delimiter // 2CREATE PROCEDURE white() 3BEGIN 4 DECLARE @count INT 5 SET @count = 1000 6 7 WHILE (@count < 9999) 8 SELECT today_close-ago_close into @is_white WHERE SC = @count ORDER BY date DESC LIMIT 4 9 CASE 10 WHEN @is_white>0 THEN INSERT INTO tableB (SC,is_white) VALUES (@count,true) ON DUPLICATE KEY UPDATE @is_white = true 11 WHEN @is_white<=0 THEN INSERT INTO tableB (SC,is_white) VALUES (@count,false) ON DUPLICATE KEY UPDATE @is_white = false 12 END 13END 14CALL white(); 15delimiter;
##エラー
`1064 - SQL構文エラーです。バージョンに対応するマニュアルを参照して正しい構文を確認してください。 : '@is_white double
DECLARE @counter INT
SET @counter =0
WHILE(@coun' 付近 3 行目`
##やりたいこと
tableA
SC | today_close | ago_close | date |
---|---|---|---|
1000 | 100 | 94 | 2019/06/20/15:00 |
2000 | 150 | 179 | 2019/06/20/15:00 |
3000 | 347 | 344 | 2019/06/20/15:00 |
1000 | 93 | 88 | 2019/06/19/15:00 |
2000 | 179 | 175 | 2019/06/19/15:00 |
3000 | 347 | 341 | 2019/06/19/15:00 |
1000 | 86 | 74 | 2019/06/18/15:00 |
2000 | 173 | 160 | 2019/06/18/15:00 |
3000 | 344 | 321 | 2019/06/18/15:00 |
1000 | 77 | 71 | 2019/06/17/15:00 |
2000 | 160 | 164 | 2019/06/17/15:00 |
3000 | 340 | 300 | 2019/06/17/15:00 |
のようにデータがtableAに格納されていて
SC=1000はtoday_close-ago_close>0が1720日において全てtrue20日において一部false
SC=2000はtoday_close-ago_close>0が17
SC=3000はtoday_close-ago_close>0が17~20日において全てtrue
なので
tableB
SC | is_white | date |
---|---|---|
1000 | true | 2019/06/20/15:00 |
2000 | false | 2019/06/20/15:00 |
3000 | true | 2019/06/20/15:00 |
としたいです
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/20 03:03
2019/06/20 03:30 編集
2019/06/20 03:36
2019/06/20 03:40