質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.40%

  • PHP

    24967questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

[PHP]配列の中から特定の条件に当てはまるレコードを抽出して処理したい

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 53

uthio

score 9

前提・実現したいこと

いつも大変お世話になっております。

DBから引っ張ってきた下記の二次元配列の中から

①statusが4で
②かつkindが重複しているものがあれば、
③updateが古いほう(より過去のもの)のstatusおよびflagだけを0にする

ということをやりたいのですが、
途中から行き詰ってしまって…皆さまのお力添えをいただきたいです。

<?php
$list = Array ( 
    [0] => Array ( [no] => 8 [kind] => 5 [flag] => 1 [status] => 4 [update] => 2014-08-20 ),
    [1] => Array ( [no] => 15 [kind] => 3 [flag] => 0 [status] => 3 [update] => 2016-12-25 ),
    [2] => Array ( [no] => 22 [kind] => 6 [flag] => 1 [status] => 4 [update] => 2017-03-01 ),
    [3] => Array ( [no] => 48 [kind] => 9 [flag] => 1 [status] => 4 [update] => 2018-05-22 ),
    [4] => Array ( [no] => 52 [kind] => 5 [flag] => 1 [status] => 4 [update] => 2014-03-04 ),
    [5] => Array ( [no] => 55 [kind] => 23 [flag] => 1 [status] => 4 [update] => 2015-09-28 ),
    [6] => Array ( [no] => 104 [kind] => 2 [flag] => 0 [status] => 3 [update] => 2018-11-11 ),
    [7] => Array ( [no] => 107 [kind] => 3 [flag] => 1 [status] => 4 [update] => 2015-04-28 ),
    [8] => Array ( [no] => 109 [kind] => 1 [flag] => 0 [status] => 3 [update] => 2016-10-15 ),
    [9] => Array ( [no] => 116 [kind] => 23 [flag] => 1 [status] => 4 [update] => 2018-07-10 ),
    [10] => Array ( [no] => 131 [kind] => 11 [flag] => 0 [status] => 3 [update] => 2013-01-02 ),
);
?>


テーブル定義は以下のようになってます。

CREATE TABLE TableName(
no int(11) unsigned auto_increment,
kind tinyint(3) unsigned,
flag tinyint(4),
status tinyint(4) DEFAULT 0,
update date,
primary key (no)
);

試したこと

まずループでstatusが4のものを抽出して、
そのうえでkindが重複しているものを抽出し、
updateが古いほうのstatusとactiveFlagを書き換える。

という手順がいいかと考えて、下記までは書いたのですが、
【kindが重複しているものをさらに抽出してそのうちupdateが古いほうを】
というのをどうすればいいか、どうにも思い浮かばない状態です。

<?php

$sql = "SELECT * from TableName where status='3' OR status='4'";
$rs = mysqli_query($link,$sql);
$count=0;
while($row = mysqli_fetch_assoc($rs)){
    $Array[$count]["no"] = $row["no"];
    $Array[$count]["kind"] = $row["kind"];
    $Array[$count]["flag"] = $row["flag"];
    $Array[$count]["status"] = $row["status"];
    $Array[$count]["update"] = $row["update"];
    $count++;
}

foreach ($Array as $val) {
    if ($val['status'] == '4') {
        //ここでkindの重複および日付の判定をしたい
        $val['status'] = 0;
        $val['activeFlag'] = 0;
    }
}
?>

DBからstatus3と4を取得しているのは他の処理でも3のレコードが必要なためです。
そもそもこの取得を一度にやろうとせず、もうちょっと考えるべきでしょうか。

間違っていたり、もっと効率的な方法がありましたら
ご指摘頂戴できれば大変助かります。

補足情報(FW/ツールのバージョンなど)

所謂レガシーシステムを扱っておりまして、
PHP環境は5.3になります。
array_columnなどが使えない状態です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • uthio

    2019/07/12 11:54

    >yambejp様
    コメントありがとうございます。
    SQL側でやる、というのがすみません、理解しきれてないですが、むしろ最終的にはSQLを更新するのが目的になります。
    特に表示させる必要はなく、実行用のPHPを作ろうと思っています。
    これで答えとしては正しいでしょうか…?

    キャンセル

  • yambejp

    2019/07/12 11:59 編集

    そういうことならSQLでstatusが4でkindがダブっている古い日付のstatusを0にするという
    処理を書けばいいような・・・

    キャンセル

  • uthio

    2019/07/12 12:13

    statusが4の時にそういう処理を書いたSQLを書く、という認識で大丈夫ですか?

    なるほど、そもそもSQLでそういう処理ができる方法を知りませんでした。。
    知識不足ですみませんでした。
    もうちょっと探してみます。

    キャンセル

回答 2

+2

SQLで処理

CREATE TABLE tbl(
no int(11) unsigned auto_increment,
kind tinyint(3) unsigned,
flag tinyint(4),
status tinyint(4) DEFAULT 0,
`update` date,
primary key (no)
);

insert into tbl values
(  8, 5,1,4,"2014-08-20"),
( 15, 3,0,3,"2016-12-25"),
( 22, 6,1,4,"2017-03-01"),
( 48, 9,1,4,"2018-05-22"),
( 52, 5,1,4,"2014-03-04"),
( 55,23,1,4,"2015-09-28"),
(104, 2,0,3,"2018-11-11"),
(107, 3,1,4,"2015-04-28"),
(109, 1,0,3,"2016-10-15"),
(116,23,1,4,"2018-07-10"),
(131,11,0,3,"2013-01-02");


だとして
statusが4で、kindがダブっていて、最新ではないデータはこう

select * from tbl as t1
where exists(
select 1 from tbl
where status=t1.status
and kind=t1.kind
and `update`>t1.`update`
)
and status=4


上記を応用してupdate

update tbl set status=0
where no in(select no from(
select no from tbl as t1
where exists(
select 1 from tbl
where status=t1.status
and kind=t1.kind
and `update`>t1.`update`
)
and status=4
) as sub)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/12 12:56

    何から何までありがとうございます。
    SQLの知識不足が根本的に問題ですね。。
    PHPで無理やりやろうと思ったところから改めねばなりません。

    頂いたものでどうにか対応できる気がします。
    まず中身をしっかり把握して進めます。

    また終わりましたらこの場を借りてご報告いたします。
    取り急ぎお礼まで。

    キャンセル

+1

PHPでやるなら

$list = [
    [ "no" => 8   ,"kind" => 5     ,"flag" => 1, "status" => 4, "update" => "2014-08-20" ],
    [ "no" => 15  ,"kind" => 3     ,"flag" => 0, "status" => 3, "update" => "2016-12-25" ],
    [ "no" => 22  ,"kind" => 6     ,"flag" => 1, "status" => 4, "update" => "2017-03-01" ],
    [ "no" => 48  ,"kind" => 9     ,"flag" => 1, "status" => 4, "update" => "2018-05-22" ],
    [ "no" => 52  ,"kind" => 5     ,"flag" => 1, "status" => 4, "update" => "2014-03-04" ],
    [ "no" => 55  ,"kind" => 23    ,"flag" => 1, "status" => 4, "update" => "2015-09-28" ],
    [ "no" => 104 ,"kind" => 2     ,"flag" => 0, "status" => 3, "update" => "2018-11-11" ],
    [ "no" => 107 ,"kind" => 3     ,"flag" => 1, "status" => 4, "update" => "2015-04-28" ],
    [ "no" => 109 ,"kind" => 1     ,"flag" => 0, "status" => 3, "update" => "2016-10-15" ],
    [ "no" => 116 ,"kind" => 23    ,"flag" => 1, "status" => 4, "update" => "2018-07-10" ],
    [ "no" => 131 ,"kind" => 11    ,"flag" => 0, "status" => 3, "update" => "2013-01-02" ],
];
$list_a = []; //status4の配列

//status4 のデータ配列を作る SQLから取れるならとったほうがいい。
for ($i = 0; $i < count($list); $i++) {
     if($list[$i]["status"] == 4){
         array_push($list_a,$list[$i]);
     }
}

//メイン処理
for ($i = 0; $i < count($list_a); $i++) {
    for ($j = $i+1; $j < count($list_a); $j++) {
        if($list_a[$i]["kind"] == $list_a[$j]["kind"]){
            if($list_a[$i]["update"] > $list_a[$j]["kind"]){
                $list_a[$j]["flag"] = 0;
                $list_a[$j]["status"] = 0;
                print_r($list_a[$j]); //printの代わりにSQLをアップデート
            }else {
                $list_a[$i]["flag"] = 0;
                $list_a[$i]["status"] = 0;
                print_r($list_a[$i]); //printの代わりにSQLをアップデート
            }
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/12 12:59

    ご丁寧にありがとうございます。
    なるほどです、私が当初やりたかったことはこういうやり方で可能なのですね。

    こちらもきちんと内容確認して対応してみたいと思います。
    yambejp様からいただいたものも含めて、終わりましたら改めてご報告いたします。

    まずはお礼を伝えさせてください。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.40%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    24967questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。