2017-04-22 37 views
0

有谁知道这个查询有什么问题吗?SQL查询与主要不在工作不起作用

这工作完全在自己:

SELECT * FROM 
(SELECT * FROM data WHERE site = '".$id."' 
AND disabled = '0' 
AND carvotes NOT LIKE '0' 
AND (time > (now() - INTERVAL 14 DAY)) 
GROUP BY car ORDER BY carvotes DESC LIMIT 0 , 10) 
X order by time DESC 

那么,这是否:

SELECT * FROM data WHERE site = '".$id."' AND disabled = '0' GROUP BY car DESC ORDER BY time desc LIMIT 0 , 30 

但是他们这样的组合:

SELECT * FROM data WHERE site = '".$id."' AND disabled = '0' AND car NOT IN (SELECT * FROM 
    (SELECT * FROM data WHERE site = '".$id."' 
    AND disabled = '0' 
    AND carvotes NOT LIKE '0' 
    AND (time > (now() - INTERVAL 14 DAY)) 
    GROUP BY car ORDER BY carvotes DESC LIMIT 0 , 10) 
    X order by time DESC) GROUP BY car DESC ORDER BY time desc LIMIT 0 , 30 

给出错误。有任何想法吗?

+0

你可以在phpmyadmin中运行这个查询吗?你期望的输出是什么? – Muntasir

+0

不起作用。 #1241 - 操作数应该包含1列。我希望能够找到所有不在第一个查询中的车(NOT IN),以便我可以将它们显示在下面的列表中。 – binnathon

+0

'.... car not in(SELECT * FROM ......' - 您应该将SELECT *改为SELECT车辆# – Muntasir

回答

1

请尝试以下...

$result = mysqli_query($con, 
         "SELECT * 
         FROM data 
         WHERE site = '" . $id . 
         "' AND disabled = '0' 
          AND car NOT IN (SELECT car 
              FROM (SELECT car, 
                  carvotes 
                FROM data 
                WHERE site = '" . $id . 
                "' AND disabled = '0' 
                 AND carvotes NOT LIKE '0' 
                 AND (time > (NOW() - INTERVAL 14 DAY)) 
                GROUP BY car 
                ORDER BY carvotes DESC 
                LIMIT 10) X 
              ) 
         GROUP BY car 
         ORDER BY time DESC 
         LIMIT 30"); 

你的问题的主要原因是,随着car NOT IN (SELECT * FROM (SELECT * ......你想的car每条记录​​的值与您的子查询返回的每一行进行比较。 IN要求您在比较的两边都有相同数量的字段。通过在子查询的两个级别使用SELECT *,您确保比较的右侧有data中的许多字段与左侧的单个字段相比较,这些字段混淆了MySQL。

由于您的目标是与单个字段(即car)进行比较,我们的子查询必须从其数据集中仅选择car字段。由于子查询结果的排序顺序对IN比较没有影响,并且由于我们最内层的查询将仅返回car,所以我删除了子查询的外层。

除了将子查询的第一部分更改为SELECT car之外,我对子查询进行的唯一其他更改是将LIMIT 0, 10更改为LIMIT 10。前者意味着限制为由0偏离第一条记录的10记录。如果您想要记录615,但是对于110冗余,这是有用的,因为LIMIT 10具有相同的影响并且稍微简单。同上LIMIT 0, 30在你的总体发言结束时。

至于声明的主体,我没有试图指定应该返回哪些字段(或这些字段的聚合函数),因为你没有声明表明你的需求/偏好是什么。如果您满意GROUP BY已经给您留下了一组仍然有效的值,那么所有的好处,但如果不是,那么我建议您将您的问题重写为具体的细节。

缺省地,MySQL排序经受GROUP BY升序排列的数据,但如果一个ORDER BY子句也存在,则它会覆盖GROUP BY的分类模式。因此,在您的GROUP BY car子句中指定DESC没有任何好处,因此我已将其删除。

有趣的一面:您可以通过指定ORDER BY NULL来覆盖GROUP BY的排序。

如果您有任何问题或意见,请随时发布相应评论。

进一步阅读

https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html - 优化您ORDER BY排序

https://dev.mysql.com/doc/refman/5.7/en/select.html - 在SELECT语句的语法 - 特别是部分具有LIMIT做。

https://www.w3schools.com/php/php_mysql_select_limit.asp - 的LIMIT

+0

这很好,先生,谢谢你:) – binnathon

+0

我正在研究我的解释。但是,如果您确信这确实是您的问题的答案,并且如果您认为这是最有用的答案,那么您可以单击答案顶部附近的打勾来接受答案。接受答案奖励回答者15分,并从StackOverflow的未答复问题列表中移除您的问题。 – toonice

0

查询本身看起来并没有特别好设计,所以它可能是一个试图准确定义你需要从这个,这应该有所帮助的情况。

但2分 - 你的第一个'不在'试图匹配汽车的价值*,(SELECT * FROM data WHERE site = '".$id."'应该可能是(SELECT car FROM data WHERE site = '".$id."'

此外,我没有看到carvotes NOT LIKE '0'这一点,这只是一个carvotes不等于'0'的情况,如果是这样,然后简化为carvotes != '0'

+0

您可以通过添加他们的语句版本来提高答案的质量这是你的建议更改纳入 – toonice

1

一个简单的解释这是你的查询:

SELECT * 
FROM data 
WHERE site = '".$id."' AND disabled = '0' AND 
     car NOT IN (SELECT * 
        FROM (SELECT * 
         FROM data 
         WHERE site = '".$id."' AND 
           disabled = '0' AND 
           carvotes NOT LIKE '0' AND 
           (time > (now() - INTERVAL 14 DAY)) 
         GROUP BY car 
         ORDER BY carvotes DESC 
         LIMIT 0 , 10 
         ) x 
        ORDER BY time DESC 
       ) 
GROUP BY car DESC 
ORDER BY time desc 
LIMIT 0 , 30 ; 

几点意见:

  • 不要用单引号包整型常量。这可能会误导人们。这可能会误导优化者。
  • 请勿在整数上使用字符串函数(例如like)。同样的道理。
  • NOT IN子查询是危险的。该构造不按照您期望的方式处理NULL值。改为使用NOT EXISTSLEFT JOIN
  • 使用子查询时,ORDER BY几乎是不合适的。
  • 决不GROUP BY使用SELECT *。这是错误的。令人高兴的是,MySQL的5.7已改变其缺省拒绝这种反模式

所以,一个更好的方式来写这个查询是这样的:

SELECT d.car, MAX(time) as time 
FROM data d LEFT JOIN 
    (SELECT d2.* 
     FROM data d2 
     WHERE d2.site = '".$id."' AND 
      d2.disabled = 0 AND 
      d2.carvotes NOT LIKE 0 AND 
      (d2.time > (now() - INTERVAL 14 DAY)) 
     GROUP BY d2.car 
     ORDER BY carvotes DESC 
     LIMIT 0 , 10 
    ) car10 
    ON d.car = car10.car 
WHERE d.site = '".$id."' AND d.disabled = 0' AND 
     car10.car IS NOT NULL 
GROUP BY car DESC 
ORDER BY MAX(time) desc 
LIMIT 0 , 30 ; 

或者,使用SELECT *并删除GROUP BY外部查询。