【问题标题】:MySQL Invalid query: Too high level of nesting for selectMySQL 无效查询:选择的嵌套级别太高
【发布时间】:2012-02-03 19:24:52
【问题描述】:

我将代码切换到安卓解决方案:

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 个表

还有其他想法吗?感谢您的帮助。

【问题讨论】:

  • 我觉得你不应该在每个 UPC 上加入一次 storeCheckRecords
  • 也许我遗漏了一些东西,但你确定你需要子查询吗?您可以通过 JOIN 来创建您的数据透视表吗?
  • 您原来的问题现在已经被时间的流沙淹没了。另外,storeCheckRecords 是一个视图吗? DRapp 的解决方案看起来越来越好。

标签: mysql pivot-table


【解决方案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;

您仍然需要编写一些代码来构建此查询,但这样做更容易一些,并且不会超出您可以运行的连接或子查询数量的任何限制。

【讨论】:

    【解决方案2】:

    这应该会在不使用子查询的情况下为您提供相同的结果:

    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)
    

    【讨论】:

    • 实际上,如果所有 4 个连接都成功,这只会返回一条记录,因为您的“WHERE”子句有一个明确的“AND”。如果您将“AND s?.upc = '...'”元素移动到 LEFT OUTER JOIN 部分,它会起作用。 where 子句意味着必须找到。
    • @DRapp 你是对的!为了清楚起见,我尝试将未加入表的内容排除在 ON 子句之外。解决我的问题...
    • 我切换到您的解决方案并发布了新错误。感谢您的帮助。
    【解决方案3】:

    我会简化为首先使用简单的 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”进行分组,并提供该组作为报告给用户的部分之间的中断。

    【讨论】:

    • 谢谢,但我将结果返回到谷歌地图,需要每个商店的所有详细信息。因此我需要 upc1,upc2,upc3... 等等。可以用这个查询来完成吗?
    • @user1184169,虽然我没有使用过谷歌地图,但我会非常惊讶他们为什么会使用非数据标准化方法来生成数据。有没有一些你正在反对的谷歌规范我可以看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2011-10-13
    • 2011-09-22
    • 1970-01-01
    • 2018-05-08
    • 2013-01-19
    相关资源
    最近更新 更多