SQL Snowflake:值不会显示在 SELECT * 搜索中,但包含在 WHERE 子句中时会显示

问题描述 投票:0回答:1

您好,提前谢谢您!

我有一个 SQL 查询,它返回状态为“活动”的课程 ID 的客户列表。我注意到总数不正确,并且有一些缺失的客户没有出现在结果列表中。当我将这些客户包含在 WHERE 子句中时,他们确实出现了。如果它们满足所有其他 WHERE 过滤器,它们不应该在没有直接引用的情况下显示吗?

查询特定客户没有出现在结果列表中的地方

 SELECT * FROM COURSES_ACTIVE
 WHERE COURSE_ID = '123aaaBBB'
 AND COURSE_STATUS = 'Active'; 

查询特定客户出现在结果列表中的位置

 SELECT * FROM COURSES_ACTIVE
 WHERE COURSE_ID = '123aaaBBB'
 AND COURSE_STATUS = 'Active'
 AND CUSTOMER_ID = '555cccDDD'; 

我尝试过的事情

最初我认为这可能与 ID 需要区分大小写有关,并且可能在之前的 SELECT 语句中,事物与 GROUP BY 的组合不正确。我确保所有 ID 都是 COLLATE("CUSTOMER_ID ", 'binary')。我已在之前的所有查询中确认 CUSTOMER_ID 确实显示,但未将它们包含在 WHERE 子句中。

当我在 SELECT CUSTOMER_ID::VARCHAR 之后粘贴“::VARCHAR”时,我已经获得了正确的 CUSTOMER_ID,但由于它不区分大小写,我担心我再次不会拥有所有 ID。

如果我在 SELECT CUSTOMER_ID::BINAY 的末尾粘贴“::BINARY”,则会收到错误“以下字符串不是合法的十六进制编码值:'888ooo000'”<--this fills with a random CUSTOMER_ID

完整代码

WITH COURSES_ALL AS (SELECT CUSTOMER_ID,
                            COURSE_ID,
                            MAX(COURSE_EXPIRATION_DATE) CURRENT_EXPIRATION_DATE
                     FROM DATABASE
                     GROUP BY CUSTOMER_ID,
                              COURSE_ID

  -- Course get new row entries so I use MAX to make sure I am only working with the most recent entry.  
  -- I have confirmed that if I run my query here, all CUSTOMER_IDs show up.

COURSES_ACTIVE AS (SELECT CUSTOMER_ID,
                          COURSE_ID,
                          CURRENT_EXPIRATION_DATE,
                          CASE
                              WHEN CURRENT_EXPIRATION_DATE < '2024-01-31' THEN 'Inactive'
                              WHEN CURRENT_EXPIRATION_DATE >= '2024-01-31' THEN 'Active'
                          END  COURSE_STATUS,
                          FROM COURSES_ALL)

 SELECT * FROM COURSES_ACTIVE
 WHERE COURSE_ID = '123aaaBBB'
 AND COURSE_STATUS = 'Active';
 --   AND CUSTOMER_ID = '555cccDDD'; //adding this line back in results in the customer showing up in the results
sql select snowflake-cloud-data-platform where-clause
1个回答
0
投票

我建议使用绑定变量来使查询更加灵活,而不是对日期和课程进行硬编码。另外,在当前查询中,您没有在第一个 CTE 中进行过滤,这似乎很浪费,如果您只是要过滤掉这些行,那么计算“非活动”没有多大意义。

所以我建议:

DECLARE @DATE DATE = '2024-01-31';
DECLARE @COURSE_ID VARCHAR = '123aaaBBB';

SELECT CUSTOMER_ID, COURSE_ID, MAX(COURSE_EXPIRATION_DATE) CURRENT_EXPIRATION_DATE
FROM DATABASE
WHERE COURSE_ID COLLATE 'en-cs' = @COURSE_ID COLLATE 'en-cs'
GROUP BY CUSTOMER_ID, COURSE_ID
HAVING MAX(COURSE_EXPIRATION_DATE) >= @DATE;

如果不需要强制执行区分大小写的排序规则,可以将其删除。

© www.soinside.com 2019 - 2024. All rights reserved.