Неверный запрос MySQL: слишком высокий уровень вложенности для выбора - PullRequest
2 голосов
/ 03 февраля 2012

Я переключил код на решение Эндрюса:

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 таблицу в соединении

Есть еще идеи? Спасибо за помощь.

Ответы [ 3 ]

1 голос
/ 03 февраля 2012

Может быть связано с MySQL bug # 41156, Список производных таблиц действует как цепочка взаимно вложенных подзапросов .

Журнал ошибок показывает, что он проверен на соответствие 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.


Относительно вашего измененного запроса в вопросе выше:

Сводные запросы могут быть сложными. Вы можете использовать метод, предложенный Эндрю в его ответ . Если вы ищете много значений UPC, вам нужно написать код приложения для построения SQL-запроса, добавив столько предложений JOIN, сколько искомых значений UPC.

В 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;

Или найти магазины, которые некоторые, но не все четыре из СКП:

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;

Или найти магазины, в которых отсутствуют все четыре СКП:

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 голосов
/ 03 февраля 2012

Я бы упростил, чтобы сначала получить все элементы с помощью простого предложения 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"«Вы изначально хотели, чтобы совпадения основывались на этой группе и предоставлялись в качестве перерыва между разделами, сообщаемыми пользователю.

0 голосов
/ 03 февраля 2012

Это должно дать вам те же результаты без использования подзапросов:

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)
...