GVKun编程网logo

php – JOINed表上的GROUP BY和ORDER BY – 复杂而缓慢(php数据表)

10

在本文中,我们将给您介绍关于php–JOINed表上的GROUPBY和ORDERBY–复杂而缓慢的详细内容,并且为您解答php数据表的相关问题,此外,我们还将为您提供关于2.(groupby)如何让分

在本文中,我们将给您介绍关于php – JOINed表上的GROUP BY和ORDER BY – 复杂而缓慢的详细内容,并且为您解答php数据表的相关问题,此外,我们还将为您提供关于2.(group by)如何让分组后,每组中的数据按时间倒序排列(group by和 order by的分组按排列)、Asp.net LINQ groupby和orderBy在日期上未检索到预期的输出、c# – LINQ – 使用OrderBy和GroupBy的子查询、c# – 实体框架 – 使用order by和group by的Linq查询的知识。

本文目录一览:

php – JOINed表上的GROUP BY和ORDER BY – 复杂而缓慢(php数据表)

php – JOINed表上的GROUP BY和ORDER BY – 复杂而缓慢(php数据表)

故事是这样的……我有用户,他们有孩子.
我想每天使用CRON JOB优惠券向在子女出生日期之间生孩子的用户发送.
我想知道谁将是用户获得优惠券和哪个孩子.
我也想为每个孩子只寄一张优惠券,孩子必须是用户最年轻的.

我有以下表格

Children
+--------------------------------------+
- Primary Key: childrenID (int)
- Index: userID (int)
- Index: childBirthDate (date)
+--------------------------------------+
- childrenID - userID - childBirthDate -
- 1          - 1      - 21/01/2000     -
- 2          - 1      - 01/11/2013     -
- 3          - 1      - 25/10/2013     -
- 4          - 2      - 01/11/2013     -
- 5          - 3      - 01/11/2013     -
+--------------------------------------+

Users
+------------------------+
- Primary Key: userID (int)
- Index: categoryGroup (varchar)
+------------------------+
- userID - categoryGroup -
- 1      - 'Group1'      -
- 2      - 'Group1'      -
- 3      - 'Group2'      -
- 4      - 'Group2'      -
+------------------------+

CuponRequests
+------------------------+
- Primary Key: ID (int)
- Index: userID (int)
- Index: cuponID (int)
+-----------------------+
- ID - cuponID - userID -
- 1  - 1       - 1      -
- 1  - 2       - 1      -
- 1  - 1       - 2      -
+-----------------------+

这基本上是具有相关列的三个主要表
我有以下SQL查询来执行和获取我需要的结果.

SELECT users.userID,
       users.categoryGroup children.childBirthDate,
       children.childrenID
FROM users,
  (SELECT *
   FROM
     (SELECT children.childrenID,
             children.childBirthDate,
             users.userID AS child_uid
      FROM children,
           users
      WHERE children.userID = users.userID
      ORDER BY children.childBirthDate DESC)t1
   GROUP BY child_uid)children
WHERE (children.childBirthDate <= DATE_SUB(CURDATE(), INTERVAL 5 MONTH))
  AND (children.childBirthDate > DATE_SUB(CURDATE() , INTERVAL 6 MONTH))
  AND (children.child_uid = users.userID)
  AND ('Group1, Group2' LIKE CONCAT('%', users.categoryGroup, '%'))
  AND NOT EXISTS
    (SELECT userID,
            cuponID
     FROM cuponRequests
     WHERE userID = users.userID
       AND cuponID = 1)
  AND userID = 1
ORDER BY children.childBirthDate DESC

对于此查询,我尝试仅在一个用户和一个优惠券上工作
但它的自然行为 – 查询正在对所有用户起作用

“cuponID”和间隔来自脚本的PHP端 – 我迭代“cupons”表(这里没有提到)并在每个“优惠券”行上执行此查询)

问题是此查询正在执行约1.5秒(O.O)
除了在CRON JOB环境中运行此脚本之外,此脚本也会在用户注册到网站后立即运行.我有96个杯子 – 这使得注册速度减慢了大约一分钟(这很多)

我想通了这个查询

SELECT *
FROM
  (SELECT children.childrenID,
          children.childBirthDate,
          users.userID AS child_uid
   FROM children,
        users
   WHERE children.userID = users.userID
   ORDER BY children.childBirthDate DESC)t1
GROUP BY child_uid

把事情放慢了.我尝试在选择查询中执行JOIN而不是选择查询,如下所示:

FROM users LEFT JOIN children ON children.userID = users.userID

但是后来我失去了“ORDER BY childBirthDate DESC”来获得这个用户最小的孩子,我失去了“GROUP BY child_uid”只让他的一个孩子

任何想法如何使事情更快但仍然有效?

P.S
抱歉我缺少英语.

编辑:

这是EXPLAIN sql的输出

+----+--------------------+---------------+-------+----------------+---------+---------+------------------------------+-------+-----------------------------------------------------+
| id |    select_type     |     table     | type  | possible_keys  |   key   | key_len |             ref              | rows  |                        Extra                        |
+----+--------------------+---------------+-------+----------------+---------+---------+------------------------------+-------+-----------------------------------------------------+
|  1 | PRIMARY            | NULL          | NULL  | NULL           | NULL    | NULL    | NULL                         | NULL  | Impossible WHERE noticed after reading const tables |
|  4 | DEPENDENT SUBQUERY | cuponRequests | ref   | userID,cuponID | userID  | 5       | const                        | 1     | Using where                                         |
|  2 | DERIVED            | <derived3>    | ALL   | NULL           | NULL    | NULL    | NULL                         | 73526 | Using temporary; Using filesort                     |
|  3 | DERIVED            | users         | index | PRIMARY        | PRIMARY | 4       | NULL                         | 69271 | Using index; Using temporary; Using filesort        |
|  3 | DERIVED            | children      | ref   | userID         | userID  | 4       | users.userID                 | 1     |                                                     |
+----+--------------------+---------------+-------+----------------+---------+---------+------------------------------+-------+-----------------------------------------------------+

解决方法:

此查询应该更快.我已经改变了出生日期的条件.

SELECT *
FROM
  (SELECT children.childrenID,
          children.childBirthDate,
          users.userID AS child_uid
   FROM children,
        users
   WHERE children.userID = users.userID
   AND children.childBirthDate <= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
   AND children.childBirthDate > DATE_SUB(CURDATE() , INTERVAL 6 MONTH)
   ORDER BY children.childBirthDate DESC)t1
GROUP BY child_uid

编辑

我能写的最快的形式的完整查询.我已从LIKE中删除%,将子查询更改为连接并删除*.关于出生日期的条件也会被移动.但是可能会有错误.

SELECT users.userID,
   users.categoryGroup, children.childBirthDate,
   children.childrenID
FROM
  (SELECT MIN(childBirthDate) AS childBirthDate, userID
      FROM children
      WHERE childBirthDate <= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
      AND childBirthDate > DATE_SUB(CURDATE() , INTERVAL 6 MONTH)
      GROUP BY userID) AS ch1
  INNER JOIN users ON users.userID = ch1.userID
  INNER JOIN children ON users.userID = children.userID AND ch1.childBirthDate = children.childBirthDate
  LEFT JOIN CuponRequests ON CuponRequests.userID = userID AND cuponID = 1
  WHERE ('Group1' LIKE users.categoryGroup OR 'Group2' LIKE users.categoryGroup)
  AND CuponRequest.ID IS NULL
  AND userID = 1
ORDER BY children.childBirthDate DESC

详细描述

>子查询可能很慢.有时优化器将无法做正确的事情.使用ON子句编写连接应该更安全.
> GROUP BY的语句对于优化器来说更加复杂.在其中写入附加条件可能会有所帮助.
>对LIKE’%something%’语句使用索引非常困难. LIKE’某事’%’或LIKE’某事’要快得多.
>有时最好将*更改为所需参数的显式列表.有时所有需要的信息都在索引中,不需要直接从表中读取.在角落的情况下,它可能会有所帮助.

2.(group by)如何让分组后,每组中的数据按时间倒序排列(group by和 order by的分组按排列)

2.(group by)如何让分组后,每组中的数据按时间倒序排列(group by和 order by的分组按排列)

 

 

比如说有表devicedata:

问题: 现在我想将devicedata这个表中的数据,先按device_id这个字段分组,然后每组中的数据按时间字段ts从大到小的排列, 如何解决呢?

错误的sql:首先分组,然后order by 排序, select * from devicedata GROUP BY device_id, id ORDER BY ts DESC,

但是这条sql查询得到的结果是:

结果是不仅没排序,而且也没分组。

再尝试一下:用子查询 先用order by将数据排序 然后将结果用group by分组,

select * from (select * from devicedata ORDER BY ts DESC) a GROUP BY a.device_id, a.id

结果:

结果是按device_id分组了, 可是组里面的数据没有按ts字段从大到小的排列,

所这样的sql还是没达到目的, 

最终正确的写法: 接下来正确的来了:select * from devicedata order by device_id, ts desc

结果:

这样就可以达到目的了,没想到吧,

 通过order by device_id, ts desc 我们可以将查询结果先按device_id分组, 再将每一组里面的按照ts字段降序(或升序)排列。

看这条sql你就明白了吧,当然肯定还有其他写法,这只是我这一刻想到的分享出来了, 大家如果有其他做法希望可以与我分享一下。

如有问题,望指教。

 

Asp.net LINQ groupby和orderBy在日期上未检索到预期的输出

Asp.net LINQ groupby和orderBy在日期上未检索到预期的输出

我正在使用linq2sql处理asp.net mvc3应用程序。

我有一个SiteLog对象类型列表,其中还包含每个对象:一个名为CLRExceptionType的字符串和一个名为EntryDate的日期。此列表包含在词典中:

private Dictionary<string,List<SiteLog>> dataBaseList = new Dictionary<string,List<SiteLog>>();
DataClasses1DataContext db = new DataClasses1DataContext("string1");
DataClasses1DataContext db2 = new DataClasses1DataContext("string2");

然后在函数中的同一控制器中填充词汇表:

   private void CreateDictionary()
{   
    dataBaseList.Add("db",db.SiteLogs.ToList());
    dataBaseList.Add("db2",db2.SiteLogs.ToList());
}

然后我有这个Linq查询:

var result =
dataBaseList.GroupBy(x => x.Key)
          .SelectMany(x =>
                        x.SelectMany(n => n.Value
                                           .GroupBy(g => g.CLRExceptionType)
                                           .Select(g => new
                                                        {
                                                          DB = x.Key,Exception = g.Key,Count = g.Count(),LastOccured = 
                                                           g.Max(y =>
                                                                 y.EntryDate)
                                                        })))
          .OrderBy(x => x.DB)
          .ThenByDescending(x => x.LastOccured);

那应该给我以下输出:

Database1:
Exception1(22次)上次发生:22.22.1989 19:30
Exception2(2次)上次发生20.5.1980 14.50

Database2
Exception1(22次)上次发生:21.10.1989 19:30
Exception2(2次)上次发生20.5 .1980 14.50

然后突然用数据库2中的新条目更新列表,所以我必须将此数据库放在最前面:
数据库2
Exception1(1次)最后
一次出现:29.07.2011 12.00 Exception1(22次)最后一次出现:21.10.1989 19:30
Exception2(2次)最后一次发生于20.5.1980 14.50

Database1:
Exception1(22次)最后一次发生于:22.10.1989 19:30
Exception2(2次)最后一次发生于20.5.1980 14.50

因此,基本上,我可以按日期对数据库中的日志进行排序,但是无法按数据库上的最后日期对数据库进行排序,如何解决此问题?观看代码(Index.cshtml):

<div id="results">

@{
    string firstTime = "";
}
 @foreach( var database in Model)
 {
       int currentCol = 0 ; 
        if (!(firstTime == database.DB))
        {
          <br/><h3> @database.DB </h3>
                currentCol = 0;
        }

           <divonclick="location.href='/logs/Details?databaseID=@database.DB&exceptionName=@database.Exception&exceptionsOccurred=@database.Count';">

                @if (database.Count > 999)
                {
                    <div><b>@database.Count</b></div>
                }
                else
                { 
                <div><b>@database.Count</b></div> 
                }
                <div> Exceptions of Type: @database.Exception</div>
                <div>Siste: @database.LastOccurred</div>
         <hr />   </div>
     currentCol += 1;
          if (currentCol == 2) { //3 columns were displayed,switch row
    currentCol = 0;
    <br/>
}

     firstTime = database.DB; 
}

</div>

提前Tnx

c# – LINQ – 使用OrderBy和GroupBy的子查询

c# – LINQ – 使用OrderBy和GroupBy的子查询

我有一些客户和相关订单.

有时我想看到每个客户的所有订单 – 直截了当.

其他时候我想看看每个客户的最后订单,如果他们没有订单我还是想看他们.

继承我的LINQ伪代码:

from customers in DataSet.Customers
join orders in DataSet.Orders on customers.CustomerId equals orders.CustomerId
into customerOrders
let customerLastOrder = customerOrders.Select(CustomerId,OrderAmount)
                                      .OrderByDescending(OrderTimestamp)
                                      .GroupBy(CustomerId)

然后我想要总计所有客户最后订单.

我不在那里,你可以看到 – 任何帮助真的很感激.

谢谢,乔

解决方法

我怀疑你想要:

from customer in DataSet.Customers
join order in DataSet.Orders on customer.CustomerId equals order.CustomerId
    into customerOrders
select new {
    CustomerId = customer.Id,LastOrderId = customerOrders.OrderByDescending(order => order.OrderTimestamp)
                                .Select(order => order.OrderId)
                                .FirstOrDefault()
};

无需再执行任何分组 – 群组加入(加入…)已经为您完成了这项任务.您正在查看单个客户的订单,因此您只需要订购它们,选择ID,然后使用FirstOrDefault()获取有序序列中的第一个值(如果序列为空,则为null).

请注意,我更改了范围变量的名称 – 在任何一点,客户指的是单个客户,而订单指的是单个订单.为了便于阅读,在您的查询中保持这种清晰的东西是值得的.

c# – 实体框架 – 使用order by和group by的Linq查询

c# – 实体框架 – 使用order by和group by的Linq查询

我有测量对象与相关的属性创建时间(DateTime)和引用(String)和一些其他值.

我想为DbContext写一个有效的linq查询

>通过给定的参考对我的Measurement对象进行分组
>通过组中的第一个Measurement的CreationTime属性或CreationTime属性的平均值对组进行排序
>将查询限制为最近的numOfEntries

(在后面的步骤中,我计算这些返回组的平均值,但我猜这与我的问题无关.)

DbContext本身具有DbSet< Measurement>称为Measurementsholding所有测量对象.

我想出了以下查询,导致一组列表正确排序,但缺少一些组之间.

var groupByReference = (from m in context.Measurements
                          orderby m.CreationTime
                          group m by new { m.Reference } into g
                          select g).Take(numOfEntries).ToList();

如何正确选择“最近”的测量组?

我正在使用带有MysqL数据库的实体框架4.4(MysqL Connector / Net 6.6.4).这个例子是简化的,如果需要,我可以进一步详细介绍和/或给出一个例子.

谢谢!

解决方法

它是方法语法(我觉得更容易阅读),但这可能会做到这一点

更新发表评论

使用.FirstOrDefault()而不是.First()

关于日期平均值,您可能必须暂停下订单,因为我目前无法访问IDE

var groupByReference = context.Measurements
                              .GroupBy(m => m.Reference)
                              .Select(g => new {Creation = g.FirstOrDefault().CreationTime,//                                              Avg = g.Average(m => m.CreationTime.Ticks),Items = g })
                              .OrderBy(x => x.Creation)
//                            .ThenBy(x => x.Avg)
                              .Take(numOfEntries)
                              .ToList();

今天关于php – JOINed表上的GROUP BY和ORDER BY – 复杂而缓慢php数据表的介绍到此结束,谢谢您的阅读,有关2.(group by)如何让分组后,每组中的数据按时间倒序排列(group by和 order by的分组按排列)、Asp.net LINQ groupby和orderBy在日期上未检索到预期的输出、c# – LINQ – 使用OrderBy和GroupBy的子查询、c# – 实体框架 – 使用order by和group by的Linq查询等更多相关知识的信息可以在本站进行查询。

本文标签: