2012-02-03 107 views
2

的過高的水平,我切換代碼安德魯斯解決方案:的MySQL查詢無效:嵌套選擇

SELECT s1.biz_name, s1.biz_info, s1.e_address, s1.e_city, s1.e_state, 
    s1.e_postal, s1.e_zip_full, s1.loc_LAT_centroid, s1.loc_LONG_centroid, 
    s1.biz_phone, s1.biz_phone_ext, s1.biz_fax, s1.biz_email, s1.web_url, 
    s2.upc as upc2, s2.retailprice as retailprice2, s2.dollar_sales as 
    dollar_sales2, s2.dollar_sales_ly as dollar_sales_ly2, s2.todaydate as 
    todaydate2, s2.datetimesql as datetimesql2, s2.shelfposition as 
    shelfposition2, s2.reg_sale as reg_sale2, s2.representative as 
    representative2, s2.notes as notes2, s3.upc as upc3, s3.retailprice as 
    retailprice3, s3.dollar_sales as dollar_sales3, s3.dollar_sales_ly as 
    dollar_sales_ly3, s3.todaydate as todaydate3, s3.datetimesql as 
    datetimesql3, s3.shelfposition as shelfposition3, s3.reg_sale as reg_sale3, 
    s3.representative as representative3, s3.notes as notes3, s4.upc as upc4, 
    s4.retailprice as retailprice4, s4.dollar_sales as dollar_sales4, 
    s4.dollar_sales_ly as dollar_sales_ly4, s4.todaydate as todaydate4, 
    s4.datetimesql as datetimesql4, s4.shelfposition as shelfposition4, 
    s4.reg_sale as reg_sale4, s4.representative as representative4, s4.notes as 
    notes4, s5.upc as upc5, s5.retailprice as retailprice5, s5.dollar_sales as 
    dollar_sales5, s5.dollar_sales_ly as dollar_sales_ly5, s5.todaydate as 
    todaydate5, s5.datetimesql as datetimesql5, s5.shelfposition as 
    shelfposition5, s5.reg_sale as reg_sale5, s5.representative as 
    representative5, s5.notes as notes5 
FROM allStores AS s1 
LEFT OUTER JOIN storeCheckRecords AS s2 
    ON s1.e_address = s2.e_address AND s2.upc = '650637119004' 
LEFT OUTER JOIN storeCheckRecords AS s3 
    ON s1.e_address = s3.e_address AND s3.upc = '650637119011' 
LEFT OUTER JOIN storeCheckRecords AS s4 
    ON s1.e_address = s4.e_address AND s4.upc = '650637374007' 
LEFT OUTER JOIN storeCheckRecords AS s5 
    ON s1.e_address = s5.e_address AND s5.upc = '650637374014' 
WHERE s2.e_address IS NOT NULL 
    OR s3.e_address IS NOT NULL 
    OR s4.e_address IS NOT NULL 
    OR s5.e_address IS NOT NULL 

這裏是新的錯誤:查詢無效:表過多; MySQL只能在一個連接中使用61個表格

任何其他想法?謝謝您的幫助。

+0

我覺得你不應該每個UPC加入'storeCheckRecords'一次。 – 2012-02-03 19:35:22

+0

也許我錯過了一些東西,但你確定你需要子查詢嗎?你可以做JOIN來創建數據透視表嗎? – 2012-02-03 19:38:43

+0

您原來的問題現在已經流失了。另外,storeCheckRecords是一個視圖嗎? DRapp的解決方案看起來越來越好。 – Andrew 2012-02-03 20:35:45

回答

0

這應該給你相同的結果,而無需使用子查詢:

SELECT s1.biz_name, 
     ... 
     s2.upc    AS upc2, 
     ... 
     s3.upc    AS upc3, 
     ... 
     s4.upc    AS upc4, 
     ... 
     s5.upc    AS upc5, 
     ... 
FROM allStores AS s1 
LEFT OUTER JOIN storeCheckRecords AS s2 ON s1.e_address = s2.e_address 
LEFT OUTER JOIN storeCheckRecords AS s3 ON s1.e_address = s3.e_address 
LEFT OUTER JOIN storeCheckRecords AS s4 ON s1.e_address = s4.e_address 
LEFT OUTER JOIN storeCheckRecords AS s5 ON s1.e_address = s5.e_address 
WHERE (s2.e_address IS NOT NULL 
OR s3.e_address IS NOT NULL 
OR s4.e_address IS NOT NULL 
OR s5.e_address IS NOT NULL) 
AND (s2.upc = '650637119004' OR s2.upc IS NULL) 
AND (s3.upc = '650637119011' OR s3.upc IS NULL) 
AND (s4.upc = '650637374007' OR s4.upc IS NULL) 
AND (s5.upc = '650637374014' OR s5.upc IS NULL) 
+0

實際上,如果所有4個連接都成功,那麼這隻會返回一條記錄,因爲您的「WHERE」子句具有明確的「AND」。如果你將你的「AND s?.upc ='...'」元素移動到左外部連接部分,它就會工作。必須找到where子句IMPLIES a。 – DRapp 2012-02-03 19:44:58

+0

@DRapp你是對的!爲了清楚起見,我嘗試將沒有加入表格的內容放在ON子句之外。修復我的答案... – Andrew 2012-02-03 19:51:40

+0

我切換到您的解決方案併發布新錯誤。感謝您的幫助。 – user1184169 2012-02-03 20:24:58

1

可能與 MySQL bug #41156, List of derived tables acts like a chain of mutually-nested subqueries

的錯誤日誌表明它反對的MySQL 5.0.72,5.1.30和6.0.7驗證。
在MySQL 5.1.37,MySQL 5.4.2(成爲5.5.something)和NDB 7.1.0中修復。


關於上述問題的重新設計的查詢:

樞軸查詢可能會非常棘手。您可以使用Andrew在his answer中建議的方法。如果搜索許多UPC值,則需要編寫應用程序代碼來構建SQL查詢,並追加與搜索的UPC值數量相同的JOIN子句。

的MySQL確實有對聯接,可以在一個單一的查詢進行數量限制,但例如,你應該沒有達到極限。也就是說,您顯示的查詢確實有效。

我假設你正在展示一個例子查詢搜索四個UPC碼,而你的應用程序可以動態地構造查詢的UPC代碼數量更多,而且可能超過61的時候。

它看起來像您的查詢的目標是返回擁有所列出的UPC代碼的至少一個商店。你可以做更多的只是在下面的查詢:

SELECT DISTINCT s.* 
FROM allStores AS s 
JOIN storeCheckRecords AS cr 
    ON s.e_address = cr.e_address 
    AND cr.upc IN ('650637119004','650637119011','650637374007','650637374014'); 

您可以在其他方面使用這種方法,例如查找具有的UPC的所有四店:

SELECT s.* 
FROM allStores AS s 
JOIN storeCheckRecords AS cr 
    ON s.e_address = cr.e_address 
    AND cr.upc IN ('650637119004','650637119011','650637374007','650637374014'); 
GROUP BY s.e_address 
HAVING COUNT(DISTINCT upc) = 4; 

或者找到存儲了一些但不是所有四個的UPC的:

SELECT s.* 
FROM allStores AS s 
JOIN storeCheckRecords AS cr 
    ON s.e_address = cr.e_address 
    AND cr.upc IN ('650637119004','650637119011','650637374007','650637374014'); 
GROUP BY s.e_address 
HAVING COUNT(DISTINCT upc) < 4; 

或者找到商店缺乏的UPC的所有四個:

SELECT s.* 
FROM allStores AS s 
JOIN storeCheckRecords AS cr 
    ON s.e_address = cr.e_address 
    AND cr.upc IN ('650637119004','650637119011','650637374007','650637374014'); 
WHERE cr.e_address IS NULL; 

你還必須寫一些代碼來構建這個查詢,但它是一個有點容易做的,它不超過上加入或可以運行子查詢的數量的任何限制。

0

我將簡化到只得到所有的元素先用一個簡單的WHERE IN子句......你似乎是做了透視表顯示T1到T2到T3到T4至T5。如果您獲取了單個行中的所有數據,那麼您可以在頂部顯示STATIC列來顯示每個行下面的詳細信息。

SELECT 
     t1.brand, 
     t1.biz_name, 
     t1.biz_info, 
     t1.e_address, 
     t1.e_city, 
     t1.e_state, 
     t1.e_postal, 
     t1.e_zip_full, 
     t1.loc_LAT_centroid, 
     t1.loc_LONG_centroid, 
     t1.biz_phone, 
     t1.biz_phone_ext, 
     t1.biz_fax, 
     t1.biz_email, 
     t1.web_url, 
     t1.upc, 
     t1.retailprice, 
     t1.dollar_sales, 
     t1.dollar_sales_ly, 
     t1.todaydate, 
     t1.datetimesql, 
     t1.shelfposition, 
     t1.reg_sale, 
     t1.representative, 
     t1.notes 
    FROM 
     storeCheckRecords as t1 
    WHERE 
     t1.upc IN ('650637119004', '650637119011', '650637374007', '650637374014') 

等..

Brand Bus Addr     UPC  Retail$  Sales  Notes 
xyz Bus Name     UPC  ... etc... Cur Yr 
     Bus Info     Shelf Info    Last Yr 
     Address, (Cit/State/Zip) 
     Lat/Long 
     Phone/Fax 
     Email/Web 

---- 
Next Entry 

確實相同的地址是相同的,而不是誰攜帶的項目?如果一個條目是「123 Main St」,另一個是「123B Main St」,並且「123 Main St - Suite B」,那麼您將找不到匹配項。

此外,你提到了一些最多有75個UPC代碼......將它們放在一個單獨的表中,並將其作爲第一個表加入到「StoreCheckRecords」中,並將它們全部取出...而不是手動鍵入所有列後綴從2到75 ...或者在下一次運行中很多隻有17個,而另一個4 ...我認爲你可能太過於固定你試圖從數據中獲得的東西。

您甚至可以通過您最初想要基於該匹配的常見「e_address」進行GROUP,並將該組作爲報告給用戶的部分之間的中斷。

+0

謝謝,但我將結果返回到谷歌地圖,並需要每個商店的所有細節。因此,我需要upc1,upc2,upc3等。可以用這個查詢完成嗎? – user1184169 2012-02-03 23:38:42

+0

@ user1184169,雖然我沒有使用谷歌地圖,但我會非常驚訝,他們爲什麼會採用非數據標準化方法來生成數據。有沒有一些你正在與谷歌合作的規範,我可以看看。 – DRapp 2012-02-04 01:36:26