mysql - 优化查询或建议 LINQ 等价物

标签 mysql sql linq linq-to-sql linq-to-objects

我有一个包含列 date_trans、time_trans、price 的表格。选择查询后,我想添加一个新列“Count”,它将计算为价格列的连续相等值,并且将从最终结果中删除具有连续相等价格的前几行。查看预期输出:

date_trans  time_trans  price   **Count**    
2011-02-22  09:39:59    58.02   1
2011-02-22  09:40:03    58.1    *ROW WILL BE REMOVED
2011-02-22  09:40:07    58.1    *ROW WILL BE REMOVED
2011-02-22  09:40:08    58.1    3
2011-02-22  09:40:10    58.15   1
2011-02-22  09:40:10    58.1    *ROW WILL BE REMOVED
2011-02-22  09:40:14    58.1    2
2011-02-22  09:40:24    58.15   1
2011-02-22  09:40:24    58.18   *ROW WILL BE REMOVED
2011-02-22  09:40:24    58.18   *ROW WILL BE REMOVED
2011-02-22  09:40:24    58.18   3
2011-02-22  09:40:24    58.15   1

请建议从表中选择的 sql 查询或 LINQ 表达式

目前,我可以选择查询并循环遍历所有选定的行,但在选择数百万行时需要几个小时。

我当前的代码:

    string query = @"SELECT date_trans, time_trans,  price
                            FROM tbl_data 
                         WHERE date_trans BETWEEN '2011-02-22' AND '2011-10-21'
                        AND time_trans BETWEEN '09:30:00' AND '16:00:00'";

            DataTable dt = oUtil.GetDataTable(query);

            DataColumn col = new DataColumn("Count", typeof(int));
            dt.Columns.Add(col);

            int priceCount = 1;
            for (int count = 0; count < dt.Rows.Count; count++)
            {
                double price = Convert.ToDouble(dt.Rows[count]["price"]);
                double priceNext = (count == dt.Rows.Count - 1) ? 0 : Convert.ToDouble(dt.Rows[count + 1]["price"]);
                if (price == priceNext)
                {
                    priceCount++;
                    dt.Rows.RemoveAt(count);
                    count--;
                }
                else
                {
                    dt.Rows[count]["Count"] = priceCount;
                    priceCount = 1;
                }
            }

最佳答案

这很有趣。我想你需要的是这样的:

SELECT MAX(date_trans), MAX(time_trans), MAX(price), COUNT(*)
FROM
    (SELECT *, ROW_NUMBER() OVER(PARTITION BY price ORDER BY date_trans, time_trans) - ROW_NUMBER() OVER(ORDER BY date_trans, time_trans) AS grp
    FROM transactions) grps
GROUP BY grp

在这里找到解决方案:http://www.sqlmag.com/article/sql-server/solution-to-the-t-sql-puzzle-grouping-consecutive-rows-with-a-common-element

更新

分组列还需要包含“价格”,否则分组可能不唯一。还有一件事是日期和时间列应该合并到日期时间列中,这样最大日期时间值在接近一天结束时开始并在下一天开始时结束的组中是正确的。 这是更正后的查询。

SELECT MAX(CAST(date_trans AS DATETIME) + CAST(time_trans AS DATETIME)) , MAX(price), COUNT(*)
FROM
    (SELECT *, 
        CAST(ROW_NUMBER() OVER(PARTITION BY price ORDER BY date_trans, time_trans) - ROW_NUMBER() OVER(ORDER BY date_trans, time_trans) AS NVARCHAR(255)) + '-' + CAST(price AS NVARCHAR(255)) AS grp
    FROM transactions
    ORDER BY date_trans, time_trans) grps
GROUP BY grp

如果将“grp”列作为字节数组或 bigint 而不是 nvarchar,查询可能会更优化。您还提到了您可能希望在组内求和的“数量”列。

关于mysql - 优化查询或建议 LINQ 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11492582/

相关文章:

c# - 查询数据表字段包含列表中任意项的行<string>

php - 用于查找具有约束的三个表之间的关系的 MySQL 查询,即使该关系不存在

sql - 在DB2中拆分VARCHAR以检索内部的值

c# - 使用自定义方法组合Where和OrderByDescending

Mysql:帮助从两个表进行查询

SQL Server 2008 - 查找具有最多行的表

c# - ObjectSet<T>.AddObject() 与 EntityCollection<T>.Add()

php - Windows 10 上的 wamp,启动 phpmyadmin 会引发错误 : Fatal error: Call to undefined function mb_detect_encoding()

mysql - 错误 121 mysql 有约束

mysql - 使用 SublimeText2 作为 MySql 查询编辑器