admin

通过SQL根据日期合并(连接)行

sql

我有下表。

Animal  Vaccine_Date    Vaccine
Dog     1/1/2016        x
Dog     2/1/2016        y
Dog     2/1/2016        z
Cat     2/1/2016        y
Cat     2/1/2016        z

我希望能够组合同一动物和同一日期的疫苗,以便它们出现在同一单元格中。下表是所需的最终结果。

Animal  Vaccine_Date    Vaccine
Dog     1/1/2016        x
Dog     2/1/2016        y,z
Cat     2/1/2016        y,z

我曾尝试创建一个易失性表来执行此操作,但是我没有任何运气,而且我认为Teradata无法识别Group_concat。


阅读 193

收藏
2021-06-07

共1个答案

admin

更新于20180419

Teradata(不确定哪个版本)添加了XMLAGG,这在这里比递归是一个更好的选择)


原始答案:

Teradata没有group_concat/listagg功能。有几种解决方法。我最喜欢的是使用递归CTE。它的效率不是很高,但是有充分的文档记录和受支持的功能。

在您的情况下:

WITH RECURSIVE recCTE AS
    (
        SELECT 
            Animal, 
            Vaccine_Date,
            CAST(min(Vaccine) as VARCHAR(50)) as vaccine_list, --big enough to hold concatenated list 
            1 as depth, --used to determine the largest/last group_concate (the full group) in the final SELECT
            Vaccine

        FROM table
        GROUP BY 1,2


        UNION ALL

        SELECT 
            recCTE.Animal,
            recCTE.Vaccine_Date,
            recCTE.Vaccine || ',' || table.Vaccine
            recCTE.depth + ,
            table.Vaccine
        FROM recCTE 
            INNER JOIN table ON
                recCTE.Animal = table.Animal AND
                recCTE.Vaccine_Date =  Table.Vaccine_Date
                table.vaccine > recCTE.vaccine
    )

    --Now select the result with the largest depth for each animal/vaccine_date combo
    SELECT * FROM recCTE
    QUALIFY ROW_NUMBER() OVER (PARTITION BY animal,vaccine_date ORDER BY depth desc) = 1

您可能需要进行一些调整(可能在连接之前先降低疫苗的值,然后进行其他操作),但是它应该使您陷入困境。您可以在此链接中查看递归CTE文档,但是它非常干燥。如果您不熟悉,那里也有很多教程。Teradata递归CTE的实现与T-
SQL和PostgresSQL的实现也非常相似。

作为另一种选择,您可以按照Teradata社区网站上该线程中tdstats.udfconcat()非常有学问的@dnoeth的说明,检查未记录的文档。

2021-06-07