1

だから私がやろうとしているのは、C# を使用して ListView オブジェクトに累積データを配置し、売上レポートの売上高を取得することです。ご覧のとおり、私のコードは非常に不安定であり、主に 2 つの MySqlCommand と DataReader を呼び出す必要がないようにしたいと考えています。どんなアドバイスでも大歓迎です!

string query = "SELECT * FROM orderlist ol "+
               "INNER JOIN orderdb o "+
               "ON ol.order_ID = o.order_ID "+
               "INNER JOIN menudb m "+
               "ON ol.menu_ID = m.menu_ID "+   
               "WHERE o.order_date >= '"+fromdate.Date()+"' AND "+
                     "o.order_date <= '"+todate.Date()+"'";
command = new MySqlCommand(query, connection);
dr = command.ExecuteReader();
string[] info = new string[15];
while(dr.Read())
{
  string query2 = "SELECT r.*, s.stock_pricePerPiece FROM recipelist r "+
                  "INNER JOIN stocksdb s ON r.stock_ID = s.stock_ID "+
                  "WHERE r.menu_ID = '"+(dr["menu_ID"].ToString())+"'";
  MySqlCommand cmd2 = new MySqlCommand(query2, connection2);
  MySqlDataReader dr2 = cmd2.ExecuteReader();
  double menu_cost = 0;
  while(dr2.Read())
  {
      menu_cost += Convert.ToDouble(dr2["stock_pricePerPiece"].ToString());
  }

info[1] = (dr["order_ID"].ToString());
info[2] = (dr["order_date"].ToString());
info[3] = (dr["menu_name"].ToString());
info[4] = (menu_cost.ToString("#0.00"));
info[5] = (dr["menu_price"].ToString());
info[6] = (Convert.ToDouble(info[5]) - menu_cost).ToString("#0.00");
this.ReportList.Items.Add(new ListViewItem(new string[] { info[1] , info[2] , info[3] , info[4] , info[5] , info[6] }));
}
4

4 に答える 4

1
string query = "SELECT ol.*, " + 
           "(SELECT SUM(stock_pricePerPiece) FROM recipelist r INNER JOIN stocksdb s ON r.stock_ID = s.stock_ID WHERE r.menu_ID = ol.menu_ID ) " +
           "AS stock_pricePerPiece FROM orderlist ol "+
           "INNER JOIN orderdb o "+
           "ON ol.order_ID = o.order_ID "+
           "INNER JOIN menudb m "+
           "ON ol.menu_ID = m.menu_ID "+ 
           "WHERE o.order_date >= '"+fromdate.Date()+"' AND "+
                 "o.order_date <= '"+todate.Date()+"'";

最初のデータリーダーからmenu_costを取得します。2番目のデータリーダーは必要ありません。

menu_cost =  Convert.ToDouble(dr["stock_pricePerPiece"].ToString());
于 2012-12-28T06:02:26.380 に答える
1

はい、1 つのクエリでこれを行うことができます。JOIN次のようにできます。

SELECT 
  r.* 
FROM  orderlist ol 
INNER JOIN orderdb    o ON ol.order_ID = o.order_ID
INNER JOIN menudb     m ON ol.menu_ID  = m.menu_ID
INNER JOIN recipelist r ON r.menu_ID   = m.menu_ID
INNER JOIN stocksdb   s ON r.stock_ID  = s.stock_ID 
WHERE o.order_date >= ...
  AND o.order_date <= ...;

更新:menu_costメニューで使用されるすべてのストック項目の合計コストであるtotal を選択するには:

SELECT 
  s.menu_cost,
  ...
FROM  orderlist ol 
INNER JOIN orderdb    o ON ol.order_ID = o.order_ID
INNER JOIN menudb     m ON ol.menu_ID  = m.menu_ID
INNER JOIN recipelist r ON r.menu_ID   = m.menu_ID
INNER JOIN
( 
   SELECT stock_ID, SUM(stock_pricePerPiece) menu_cost
   FROM stocksdb 
   GROUP BY stock_ID
)  s ON r.stock_ID  = s.stock_ID 
WHERE o.order_date >= ...
  AND o.order_date <= ...;
于 2012-12-28T05:59:06.770 に答える
1

それを行うと実際のパフォーマンスの問題が発生する可能性があります.SQLを動的に作成して実行するのは時間がかかるため、実際には効率的ではありません.このジョブはDBMSに任せ、結合またはビューを使用して目的のデータセットを構築し、データベースにこれを管理させてから、単一のステートメントを実行すると、大量のデータで違いを感じるでしょう。

興味がある場合に備えて、クエリの実行計画を生成してパフォーマンスを確認できます。mysql についてはわかりませんが、SQLServer などの他の DBMS では、同じ結果をより良いパフォーマンスで達成するための最適化手順も提供されます。

于 2012-12-28T06:03:45.110 に答える
0

これが、蓄積された回答に基づいて作成した SQL クエリです。皆さんと共有する必要があると思います。答えてくれてありがとう!

SELECT 
DISTINCT o.order_ID, o.order_date, o.order_status, m.*, mc.menu_cost
FROM  orderlist ol 
INNER JOIN orderdb    o ON ol.order_ID = o.order_ID
INNER JOIN menudb     m ON ol.menu_ID  = m.menu_ID
INNER JOIN
(SELECT SUM(s.stock_pricePerPiece * r.recipe_quantity) AS menu_cost, m.menu_ID
    FROM recipelist r
        INNER JOIN stocksdb s ON r.stock_ID = s.stock_ID
        INNER JOIN menudb m ON r.menu_ID= m.menu_ID
    GROUP BY r.menu_ID
) 
mc ON m.menu_ID = mc.menu_ID
WHERE o.order_date >= '2012-12-22 00:00:00'
  AND o.order_date <= '2012-12-22 23:59:59';
于 2012-12-28T15:51:48.110 に答える