2017-04-22 39 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外部查詢。