sql >> データベース >  >> Database Tools >> phpMyAdmin

値が小さい前のレコードに時間がかかりすぎて失敗した場合にのみ、レコードを選択します

    これが質問1の解決策です。これは、全表スキャンと依存サブクエリが多数あるため、はるかに高速に実行されます。ここでは、せいぜい1つのテーブルスキャンしかありません(データの大きさやメモリの量によっては、一時テーブルもあります)。ここであなたの質問に簡単に合わせることができると思います。質問2(私は実際には読んでいません)もおそらく答えられます。where date_column = whateverを追加するだけで簡単にできるからです。

    select * from (
        select
        t.*,
        if(@prev_toner < Remain_Toner_Black and @prev_sn = SerialNumber, 1, 0) as select_it,
        @prev_sn := SerialNumber,
        @prev_toner := Remain_Toner_Black
        from
        Table1 t
        , (select @prev_toner:=0, @prev_sn:=SerialNumber from Table1 order by SerialNumber limit 1) var_init
        order by SerialNumber, id
    ) sq  
    where select_it = 1
    
    • sqlfiddle でライブで動作することを確認してください

    編集:

    説明:

    この行で

        , (select @prev_toner:=0, @prev_sn:=SerialNumber from Table1 order by SerialNumber 
    

    変数@prev_tonerを初期化するだけです および@prev_sn 急いで。これは、クエリにこの行がまったく含まれていないのと同じですが、クエリの前に書き込みます

    SET @prev_toner = 0;
    SET @prev_sn = (select serialnumber from your_table order by serialnumber limit 1);
    SELECT ...
    

    では、なぜ@prev_snに値を割り当てるクエリを実行するのでしょうか。また、シリアル番号で並べ替えるのはなぜですか。による順序は非常に重要です。による順序がないと、行が返される保証された順序はありません。また、変数を使用して前の行の値にアクセスするため、同じシリアル番号を「グループ化」することが重要です。

    select句の列は次々に評価されるため、最初にこの行を選択することが重要です

    if(@prev_toner < Remain_Toner_Black and @prev_sn = SerialNumber, 1, 0) as select_it,
    

    これらの2行を選択する前に

    @prev_sn := SerialNumber,
    @prev_toner := Remain_Toner_Black
    

    何故ですか?最後の2行は、現在の行の値だけを変数に割り当てます。そのため、この行で

    if(@prev_toner < Remain_Toner_Black and @prev_sn = SerialNumber, 1, 0) as select_it,
    

    変数は前の行の値を保持します。そして、ここで行うことは、「Remain_Toner_Black列の前の行の値が現在の行の値よりも小さい場合および 前の行のシリアル番号は実際の行のシリアル番号と同じで、1を返し、それ以外の場合は0を返します。 "

    次に、外側のクエリで「上記が1を返したすべての行を選択してください」と簡単に言うことができます。

    クエリが与えられた場合、これらすべてのサブクエリは必要ありません。それらは非常に高価で不要です。実際、それは非常に正気ではありません。クエリのこの部分では

        SELECT  a.ID, 
                a.Time, 
                a.SerialNumber, 
                a.Remain_Toner_Black,
                a.Remain_Toner_Cyan,
                a.Remain_Toner_Magenta,
                a.Remain_Toner_Yellow,
                (
                    SELECT  COUNT(*)
                    FROM    Reports c
                    WHERE   c.SerialNumber = a.SerialNumber AND
                            c.ID <= a.ID) AS RowNumber
        FROM    Reports a
    

    テーブル全体を選択します およびすべての行に対して そのグループ内の行を数えます。これは依存サブクエリです。ある種の行番号を持っているだけです。次に、これを2回実行します。これにより、これら2つの一時テーブルを結合して、前の行を取得できます。本当に、パフォーマンスがひどいのも不思議ではありません。

    だから、あなたのクエリに私のソリューションを調整する方法は? Remain_Toner_Blackの前の行を取得するために使用した1つの変数の代わりに、黒、シアン、マゼンタ、および黄色の色に4つを使用します。そして、すでに行ったように、PrintersandCustomersテーブルに参加するだけです。注文を忘れないでください。




    1. PHPのMySQLへの挿入構文エラー

    2. ManagementStudioのデフォルトのファイル保存場所

    3. SQLServer管理オブジェクト

    4. SSDT(SQL Serverデータツール)のインストール時にエラーが発生しました