Combine(concatenate) rows based on dates via SQL

自古美人都是妖i 提交于 2019-12-24 06:49:12

问题


I have the following table.

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

I want to be able to combine vaccines that are on the same animal and same date, so that they appear in the same cell. The table below is what the desired end result would be.

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

I have tried to create a volatile table to do so but I am not having any luck and I don't think Teradata recognizes the Group_concat.


回答1:


UPDATED 20180419

Teradata (not sure which version) has added XMLAGG which would be a better choice here than recursive)


Original answer:

Teradata doesn't have group_concat/listagg functionality. There are a couple of workarounds. My favorite is to use a recursive CTE. It's not terribly efficient, but it's well documented and supported functionality.

In your case:

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

You may have to tweak that a little bit (possibly trim the vaccine values before concatenating and whatnot), but it should get you in the ballpark. You can check out the recursive CTE documentation at this link, but it's pretty dry. There are a lot of tutorials out there too, if you are unfamiliar. Teradata's implementation of recursive CTE is very similar to T-SQL and PostgresSQL's implementation as well.

As another option you can check out the as-of-yet undocumented tdstats.udfconcat() as explained by the extremely knowledgable @dnoeth in this thread on Teradata Community website.




回答2:


Try this. STUFF function is an ideal for such situations:

  SELECT
     Animal, Vaccine_Date,
     STUFF(
         (SELECT DISTINCT ',' + Vaccine
          FROM TableName
          WHERE Animal = a.Animal AND Vaccine_Date = a.Vaccine_Date
          FOR XML PATH (''))
          , 1, 1, '')  AS VaccineList
FROM TableName AS a
GROUP BY Animal, Vaccine_Date



回答3:



You can use this Query,

  SELECT 
   Animal,Vaccine_Date,
   LISTAGG(Vaccine, ',') WITHIN GROUP (ORDER BY Vaccine) "names"
   FROM table_name
   GROUP BY Vaccine

Hope you got it



来源:https://stackoverflow.com/questions/39533181/combineconcatenate-rows-based-on-dates-via-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!