【问题标题】:WHERE IN (SELECT) statement breaks query, when there is a WITH statement present当存在 WITH 语句时,WHERE IN (SELECT) 语句会中断查询
【发布时间】:2021-11-16 00:52:38
【问题描述】:

这很好用:

SELECT qaer_name, 
       AVG(Minutes(QA_Time)) AS avg_minutes, 
       COUNT(Zendesk_URL) AS num_tickets
FROM zendeskData
WHERE qaer_name IN (SELECT Name FROM qaers)
AND tags LIKE '%cosmetic%'                    
AND CAST(sub_to_qa_date AS DATE) >= CAST('${new Date('2021-11-10')}' AS DATE)
GROUP BY qaer_name

但这会因错误而中断:TypeError: Cannot read property '0' of undefined

WITH cosmetic AS (
  SELECT qaer_name, 
         AVG(Minutes(QA_Time)) AS avg_minutes, 
         COUNT(Zendesk_URL) AS num_tickets
  FROM zendeskData
  WHERE qaer_name IN (SELECT Name FROM qaers)
  AND tags LIKE '%cosmetic%'                    
  AND CAST(sub_to_qa_date AS DATE) >= CAST('${new Date('2021-11-10')}' AS DATE)
  GROUP BY qaer_name
)
SELECT * FROM cosmetic

这个没有报错(但没有做我想要的过滤):

WITH cosmetic AS (
  SELECT qaer_name, 
         AVG(Minutes(QA_Time)) AS avg_minutes, 
         COUNT(Zendesk_URL) AS num_tickets
  FROM zendeskData
  --WHERE qaer_name IN (SELECT Name FROM qaers)
  WHERE tags LIKE '%cosmetic%'                    
  AND CAST(sub_to_qa_date AS DATE) >= CAST('${new Date('2021-11-10')}' AS DATE)
  GROUP BY qaer_name
)
SELECT * FROM cosmetic

但是,这个确实给出了同样的错误:TypeError: Cannot read property '0' of undefined

WITH cosmetic AS (
  SELECT qaer_name, 
         AVG(Minutes(QA_Time)) AS avg_minutes, 
         COUNT(Zendesk_URL) AS num_tickets
  FROM zendeskData
  WHERE tags LIKE '%cosmetic%'                    
  AND CAST(sub_to_qa_date AS DATE) >= CAST('${new Date('2021-11-10')}' AS DATE)
  GROUP BY qaer_name
)
SELECT * 
FROM cosmetic
WHERE qaer_name IN (SELECT Name FROM qaers)

为什么WHERE IN (SELECT) 语句只有在存在WITH 语句时才会破坏它?

编辑: 这也会产生同样的错误。

let data = Database.alasql(`
  ;WITH cosmetic AS (
    SELECT qaer_name, 
          AVG(Minutes(QA_Time)) AS avg_minutes, 
          COUNT(Zendesk_URL) AS num_tickets
    FROM zendeskData z
    WHERE EXISTS (SELECT 1 FROM qaers q WHERE z.qaer_name = q.Name) 
    AND tags LIKE '%cosmetic%'                    
    AND CAST(sub_to_qa_date AS DATE) >= CAST('${new Date('2021-11-10')}' AS DATE)
    GROUP BY qaer_name
  )
  SELECT * 
  FROM cosmetic
`);
Logger.log(data);

【问题讨论】:

  • 您的IN 将永远中断。 IN 将您的字段与您的 subquery return field 匹配,在这种情况下,所有字段都是错误的。
  • IN 并不总是中断。它在第一个示例中没有中断。我进行了编辑以更清楚地表明SELECT * FROM qaers 实际上是一个具有单个字段的表。运行编辑后的SELECT Name FROM qaers 会出现同样的错误。
  • 你能把你的with改成;with看看会发生什么吗?
  • 如编辑中所示运行它,结果相同。
  • 您的WHERE EXISTS (SELECT 1 FROM qaers q WHERE z.qaer_name = q.Name) 确实与我的WHERE qaer_name IN (SELECT Name FROM qaers) 在没有WITH 的第一个变体中给出相同的结果。

标签: sql google-apps-script alasql


【解决方案1】:

我不知道为什么我原来的方法不起作用,但我想出了一个变通方法。

除了创建qaers 表,然后在以后的查询中选择该表之外,我的替代方法是将表设为 JS 数组,然后将其传递到查询中,并将其格式化为列表。

这给出了我正在寻找的正确结果,因为它允许我使用名称列表和 WITH 语句,这将是必要的,因为我使查询更加复杂。

let qaers = Database.alasql(`
  SELECT MATRIX Name 
  FROM annotatorData 
  WHERE Pod_Number = 'QA'
`);

let data = Database.alasql(`
  WITH cosmetic AS (
    SELECT qaer_name, 
          AVG(Minutes(QA_Time)) AS avg_minutes, 
          COUNT(Zendesk_URL) AS num_tickets
    FROM zendeskData
    WHERE qaer_name IN ('${qaers.join("','")}')
    AND tags LIKE '%cosmetic%'                    
    AND CAST(sub_to_qa_date AS DATE) >= CAST('${new Date('2021-11-10')}' AS DATE)
    GROUP BY qaer_name
  )
  SELECT * 
  FROM cosmetic
`)

【讨论】:

  • 如果 alasql 支持,请使用 exists 而不是 in
  • 当子查询结果很大时,EXISTS 子句比 IN 快很多。相反,当子查询结果非常小时,IN 子句比 EXISTS 快。 link我的子查询结果很小。
猜你喜欢
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 2021-12-23
  • 2013-10-10
  • 2011-01-12
  • 2018-03-08
  • 1970-01-01
相关资源
最近更新 更多