我有一张表' AnimalInformation'并希望根据购买日期透视列,如下所示。我尝试过使用枢轴但没有完全按照我的要求进行操作。你能帮我一点吗?以下提供的所有信息
Result should look like
PurchaseDate | CatInfo| DogInfo | FishInfo | CatDate | DogDate | FishDate
----------------------------------------------------------------------------------
1/1/2016 | Good | Fair | NotGood | 10/10/2016 | 11/10/2016 | 12/10/2016
2/2/2016 | Bad | Good | Good | 9/9/2016 | 10/9/2016 | 11/9/2016
##Table##
CREATE TABLE [dbo].[AnimalInformation](
[UniqueId] [int] IDENTITY(1,1) NOT NULL,
[PurchaseDate] [datetime] NOT NULL,
[Animal] [nvarchar](50) NOT NULL,
[HealthDate] [datetime] NOT NULL,
[AnimalCondition] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_AnimalInformation] PRIMARY KEY CLUSTERED
(
[UniqueId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
## Insert Statement ##
Insert into AnimalInformation values ('1/1/2016' ,'Cat','10/10/2016','Good')
Insert into AnimalInformation values ('1/1/2016' ,'Dog','11/10/2016','Fair')
Insert into AnimalInformation values ('1/1/2016' ,'Fish','12/10/2016','Not Good')
Insert into AnimalInformation values ('2/2/2016' ,'Cat','9/9/2016','Bad')
Insert into AnimalInformation values ('2/2/2016' ,'Dog','10/9/2016','Good')
Insert into AnimalInformation values ('2/2/2016' ,'Fish','11/9/2016','Good')
## My Query ##
SELECT * FROM
(
SELECT
PurchaseDate,
Animal,
AnimalCondition,
HealthDate,
(Animal + 'Info') AnimalHealthInfo,
(Animal + 'Date') AnimalHealthDate
FROM
AnimalInformation
) X
PIVOT ( MAX(AnimalCondition) FOR AnimalHealthInfo IN ([CatInfo],[DogInfo],[FishInfo] )
) As P1
PIVOT ( MAX(HealthDate) FOR AnimalHealthDate IN ([CatDate],[DogDate],[FishDate])
) AS P2
答案 0 :(得分:1)
条件聚合是你可以做到的一种方式。
SELECT
PurchaseDate
,MAX(CASE WHEN Animal = 'Cat' THEN AnimalCondition END) as CatInfo
,MAX(CASE WHEN Animal = 'Dog' THEN AnimalCondition END) as DogInfo
,MAX(CASE WHEN Animal = 'Fish' THEN AnimalCondition END) as FishInfo
,MAX(CASE WHEN Animal = 'Cat' THEN HealthDate END) as CatDate
,MAX(CASE WHEN Animal = 'Dog' THEN HealthDate END) as DogDate
,MAX(CASE WHEN Animal = 'Fish' THEN HealthDate END) as FishDate
FROM
AnimalInformation
GROUP BY
PurchaseDate
然后有一种方法,你和其他几个人正在尝试哪个MikkaRin正确但忘记了列名:
SELECT
PurchaseDate
,MAX(CatI) as CatInfo
,MAX(DogI) as DogInfo
,MAX(FishI) as FishInfo
,MAX(CatD) as CatDate
,MAX(DogD) as DogDate
,MAX(FishD) as FishDate
FROM
(SELECT
PurchaseDate
,HealthDate
,AnimalCondition
,Animal + 'I' as AnimalInfo
,Animal + 'D' as AnimalDate
FROM
AnimalInformation) t
PIVOT
(
MAX(AnimalCondition)
FOR AnimalInfo IN (CatI,DogI,FishI)
) p
PIVOT
(
MAX(HealthDate)
FOR AnimalDate IN (CatD,DogD,FishD)
) p2
GROUP BY
PurchaseDate
或加入两个支柱:
;WITH cteHealthInfo AS (
SELECT PurchaseDate, Cat as CatInfo, Dog as DogInfo, Fish as FishInfo
FROM
(SELECT PurchaseDate, AnimalCondition, Animal
FROM
AnimalInformation) t
PIVOT
(
MAX(AnimalCondition)
FOR Animal IN (Cat,Dog,Fish)
) p
)
, cteHealthDate AS (
SELECT PurchaseDate, Cat as CatDate, Dog as DogDate, Fish as FishDate
FROM
(SELECT PurchaseDate, HealthDate, Animal
FROM
AnimalInformation) t
PIVOT
(
MAX(HealthDate)
FOR Animal IN (Cat,Dog,Fish)
) p
)
SELECT
i.*
,d.CatDate
,d.DogDate
,d.FishDate
FROM
cteHealthInfo i
INNER JOIN cteHealthDate d
ON i.PurchaseDate = d.PurchaseDate
就个人而言,我觉得条件聚合提供了最灵活的解决方案,对于这样的案例,代码量最少。我确实看到了使用unpivot然后使用pivot的有趣解决方案,但这需要数据类型保持一致。
答案 1 :(得分:1)
SELECT PurchaseDate,
max([CatInfo]),
max([DogInfo]),
max([FishInfo]),
max([CatDate]) ,
max([DogDate]) ,
max([FishDate])
FROM
(
SELECT
PurchaseDate,
--Animal,
AnimalCondition,
HealthDate,
(Animal + 'Info') AnimalHealthInfo,
(Animal + 'Date') AnimalHealthDate
FROM
@AnimalInformation
) X
PIVOT ( MAX(AnimalCondition) FOR AnimalHealthInfo IN ([CatInfo],[DogInfo],[FishInfo] )
) As P1
PIVOT ( MAX(HealthDate) FOR AnimalHealthDate IN ([CatDate],[DogDate],[FishDate])
) AS P2
group by PurchaseDate