问题
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