繁体   English   中英

在使用具有 DISTINCT function 的 LISTAGG 或 REGEXP_REPLACE 时需要帮助

[英]Need help in using LISTAGG or REGEXP_REPLACE with DISTINCT function

SELECT  distinct ID,LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') 
WITHIN GROUP(ORDER BY CAST(PAGE_NBR as INT)) AS No_Of_Views
FROM db_name.schema_name.tbl
WHERE date_created = '2022-01-21'
AND flg_col = '0'
AND src_id NOT IN ('0','3','4','5')
AND ID='0127435345345'
group by ID;

当我运行上述查询时,我得到了不同的值

21/01/2022 20:21:17,21/01/2022 20:21:31,21/01/2022 20:22:23,21/01/2022 20:22:33

当我尝试使用 CTE 运行相同的查询时,我没有得到不同的结果。 无论如何都要使用 CTE 形成一个查询来获取不同的值:

WITH CTE AS (
SELECT
 ID,CREATE_TS,
PAGE_NBR::INT AS PAGE_NBR
FROM db_name.schema_name.tbl 
WHERE flg_col = '0'
AND src_id NOT IN ('0','3','4','5')
AND CREATE_DT = ''2022-21-01''
AND ID='0127435345345'
ORDER BY PAGE_NBR
)
SELECT
 ID,
LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') WITHIN GROUP(ORDER BY CREATE_TS) AS No_Of_Views 
FROM CTE
GROUP BY ID;

当我使用不同的内部 LISTAGG 即。 LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') 我收到 SQL 编译错误:[CTE.CREATE_TS] 不是按表达式的有效顺序

我希望结果与第一个查询相同,但我需要尝试第二种方法..

首先,您的第二个陈述与第一个不同。 第一个有:

LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') 
WITHIN GROUP(ORDER BY CAST(PAGE_NBR as INT)) AS No_Of_Views

第二个有:

LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') WITHIN GROUP(ORDER BY CREATE_TS) AS No_Of_Views 

关于 DISTINCT 错误,如文档中所述,如果您指定 DISTINCT 和 WITHIN GROUP,则两者必须引用同一列。

https://docs.snowflake.com/en/sql-reference/functions/listagg.html#usage-notes

所以你的最后一句话应该是这样的:

...
SELECT
 ID,
LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') WITHIN GROUP(ORDER BY to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss')) AS No_Of_Views 
FROM CTE
GROUP BY ID;

唔。 所以我先抓了你SQL,编了一些假数据,去掉了无所谓的部分:

WITH data AS (
  SELECT id, to_timestamp(CREATE_TS) as CREATE_TS, PAGE_NBR  FROM values
  ( 1, '2022-01-01 01:23:34', '1'),
  ( 1, '2022-01-02 01:23:34', '2'),
  ( 2, '2022-01-03 01:23:34', '3'),
  ( 3, '2022-01-04 01:23:34', '4')
  v( id, CREATE_TS, PAGE_NBR )
)
SELECT distinct 
    ID,
    LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') WITHIN GROUP(ORDER BY CAST(PAGE_NBR as INT)) AS No_Of_Views
FROM data
group by ID;

我得到:

ID NO_OF_VIEWS
2 2022 年 1 月 3 日 01:23:34
3 2022 年 1 月 4 日 01:23:34
1 01/01/2022 01:23:34,01/02/2022 01:23:34

然后我戳入 SQL 的第二块,拉出所有没有任何意义的相同位,并具有:

WITH data AS (
  SELECT id, to_timestamp(CREATE_TS) as CREATE_TS, PAGE_NBR  FROM values
    ( 1, '2022-01-01 01:23:34', '1'),
    ( 1, '2022-01-02 01:23:34', '2'),
    ( 2, '2022-01-03 01:23:34', '3'),
    ( 3, '2022-01-04 01:23:34', '4')
  v( id, CREATE_TS, PAGE_NBR )
), CTE AS (
    SELECT
      ID, 
      CREATE_TS,
      PAGE_NBR::INT AS PAGE_NBR
    FROM data
)
SELECT
 ID,
LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') WITHIN GROUP(ORDER BY CREATE_TS) AS No_Of_Views 
FROM CTE
GROUP BY ID;

这仍然有效:

ID NO_OF_VIEWS
2 2022 年 1 月 3 日 01:23:34
3 2022 年 1 月 4 日 01:23:34
1 01/01/2022 01:23:34,01/02/2022 01:23:34

在您的第一个查询中, distinct什么都不做,因为您的代码有一个 group by 子句。

在您之前的问题中,您希望数组中有不同的值,但是要按替代列( PAGE_NBR )对它们进行排序,您不能在 LIST_AGG 中使用 DISTINCT 子句,因此 Lukasz soultion 使用 CTE 来复制数据。

所以在这里展示:

WITH data AS (
  SELECT id, to_timestamp(CREATE_TS) as CREATE_TS, PAGE_NBR  FROM values
    ( 1, '2022-01-01 01:23:34', '1'),
    ( 1, '2022-01-01 01:23:34', '2'),
    ( 1, '2022-01-01 01:23:34', '3'),
    ( 1, '2022-01-02 01:23:34', '2'),
    ( 2, '2022-01-03 01:23:34', '3'),
    ( 3, '2022-01-04 01:23:34', '4')
  v( id, CREATE_TS, PAGE_NBR )
), cte AS (
  SELECT ID, CREATE_TS, PAGE_NBR::INT AS VISIT_PAGE_NBR
  FROM data
  --WHERE FLG_COLUMN = '0'
  --  AND SOURCE_CD NOT IN ('1','2','3','4')
  --  AND DATE_CR = '2022-01-01'
  QUALIFY ROW_NUMBER() OVER(PARTITION BY ID,CREATE_TS ORDER BY VISIT_PAGE_NBR::INT) = 1
)
SELECT ID,
    LISTAGG(to_varchar(CREATE_TS, 'mm/dd/yyyy hh:mi:ss'), ',') WITHIN GROUP(ORDER BY VISIT_PAGE_NBR) AS No_Of_Views
FROM cte
GROUP BY ID;

给出:

ID NO_OF_VIEWS
1 01/01/2022 01:23:34,01/02/2022 01:23:34
2 2022 年 1 月 3 日 01:23:34
3 2022 年 1 月 4 日 01:23:34

QUALIFY ROW_NUMBER() OVER(PARTITION BY ID,CREATE_TS ORDER BY VISIT_PAGE_NBR::INT) = 1正在执行仅允许不同ID,CREATE_TS

通过将它们全部编号,并过滤掉任何不是第一行的内容。

因此,当使用外部 LIST_AGG 时,可以删除您最初拥有的 DISTINCT。 并且可以使用 VISIT_PAGE_NBR 的顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM