【问题标题】:Is there a more efficient way of getting data from 5 tables other than what I am doing now?除了我现在正在做的事情之外,还有更有效的方法从 5 个表中获取数据吗?
【发布时间】:2012-12-28 05:52:09
【问题描述】:

所以我要做的是使用 C# 将累积数据放在 ListView 对象上,然后获取销售报告的销售额。如您所见,它非常不稳定,我的代码就是,我主要想删除必须调用两个 MySqlCommands 和 DataReaders。任何建议将不胜感激!

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] }));
}

【问题讨论】:

  • 我想我也应该说THE CODE IS UNTESTED 并且是在提问之前提出的:)

标签: c# mysql select join


【解决方案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,这是菜单上使用的所有库存项目的总成本:

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 <= ...;

【讨论】:

  • @JohnErnestGuadalupe - 它在哪里?我在你的代码中看不到它。
  • @JohnErnestGuadalupe 抱歉,刚刚看到,这个演员表来自哪个表?它是按菜单还是按库存?
  • @JohnErnestGuadalupe 查看我的编辑。我不确定,可能你需要使用 group by。
  • @JohnErnestGuadalupe sINNER JOIN 中子查询的别名。对于错误,不要进行两个 while 循环来读取结果,您只需要一个 while 循环来从数据读取器中读取。也可以直接在 management studio 上尝试查询,并确保它可以正常工作并且其结果是您正在寻找的结果。
  • @JohnErnestGuadalupe - 你能用给你错误的代码更新你的问题吗?是不是直接试了,效果很好?
【解决方案2】:

你这样做的方式可能会给你带来真正的性能问题,动态创建 SQL 并执行它们并不是很有效,因为它们在时间上很昂贵,你应该把这项工作留给 DBMS,使用joinsviews建立你想要的数据集,让你的数据库来管理,然后执行一条语句,你会感受到大量数据的不同。

仅针对您感兴趣的情况,您可以生成查询的execution plan 以查看其性能如何,不了解 mysql 但其他 DBMS(如 SQLServer)为您提供甚至优化步骤以实现相同的结果和更好的性能.

【讨论】:

    【解决方案3】:
    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,您不需要第二个数据读取器

    menu_cost =  Convert.ToDouble(dr["stock_pricePerPiece"].ToString());
    

    【讨论】:

    • 实际上第二个数据读取器添加了所有股票的stock_pricePerPiece,它们在具有相同menu_ID的同一菜单上使用。你如何在一个查询中得到它?
    • 我的dr = command.ExecuteReader() 上出现index was outside the bound of the array 错误?
    【解决方案4】:

    这是我根据累积的答案进行的 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';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多