SQL枢轴以不同的方式

时间:2014-07-10 15:50:44

标签: sql sql-server sql-server-2008

我有一张桌子。该表具有患者ID和审核ID。对于单次检查,可以收集许多血液样本。对于患者ID P1 ,有两条评论(1,12)。但对于其他患者,有一篇评论。我希望首先以轮回方式检查所有患者,然后进行第二次检查,依此类推。 (它们按ReviewID / Date排序)是否可以做到!感谢。

enter image description here

下面给出了db create,insert:

的代码块
  

CREATE TABLE [dbo].[BloodSampleData]( [PatientID] [nchar](10) NULL, [ReviewID] [int] NULL, [Date] [date] NULL, [BloodSampleID] [int] NULL ) ON [PRIMARY]

     

INSERT INTO [Test].[dbo].[BloodSampleData] ([PatientID] ,[ReviewID] ,[Date] ,[BloodSampleID]) VALUES ('P1',1,convert(datetime,'18-06-08 00:00:00 AM',5),4) ,('P1',1,convert(datetime,'18-06-09 00:00:00 AM',5),3) ,('P1',1,convert(datetime,'18-06-10 00:00:00 AM',5),4) ,('P1',1,convert(datetime,'18-07-11 00:00:00 AM',5),3) ,('P1',12,convert(datetime,'28-06-13 00:00:00 AM',5),5) ,('P1',12,convert(datetime,'11-02-14 00:00:00 AM',5),6) ,('P2',10,convert(datetime,'21-06-07 00:00:00 AM',5),2) ,('P2',10,convert(datetime,'14-02-08 00:00:00 AM',5),3) ,('P3',22,convert(datetime,'28-06-13 00:00:00 AM',5),7)

1 个答案:

答案 0 :(得分:1)

  “无论谁与怪物打架,都应该确保他不会成为   这个过程中的怪物。当你长时间凝视深渊时   深渊也凝视着你。“

愿上帝怜悯我的灵魂,因为这段代码非常接近。我不认为这是其他人建议的枢轴/交叉标签的情况(虽然我很想得到纠正,你不必使用下面的怪物),因为我们没有将列值分成列而是以不同的方式去正常化。

考虑可能更容易生成的其他格式,如果不像我那样厌恶你,请使用下面的内容。

DROP TABLE dbo.Report
CREATE TABLE dbo.Report (
PatientID varchar(10) NOT NULL,
ReviewId int NOT NULL
)

DECLARE c_patients CURSOR
READ_ONLY
FOR SELECT DISTINCT PatientID, ReviewId FROM dbo.BloodSampleData ORDER BY PatientID ASC

DECLARE @patient_id varchar(10), @review_id int
OPEN c_patients
FETCH NEXT FROM c_patients INTO @patient_id, @review_id
WHILE (@@fetch_status <> -1)
BEGIN
    IF (@@fetch_status <> -2)
    BEGIN
        INSERT INTO dbo.Report (PatientID, ReviewId) VALUES (@patient_id, @review_id)

        DECLARE c_reviews CURSOR
        READ_ONLY
        FOR SELECT [Date], [BloodSampleID] FROM dbo.BloodSampleData WHERE PatientID = @patient_id AND ReviewId = @review_id ORDER BY [Date] ASC

        DECLARE @date DATE, @blood_sample_id INT, @review_num int
        OPEN c_reviews
        SET @review_num = 0
        FETCH NEXT FROM c_reviews INTO @date, @blood_sample_id
        WHILE (@@fetch_status <> -1)
        BEGIN
            IF (@@fetch_status <> -2)
            BEGIN

                IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Report' AND COLUMN_NAME LIKE '%' + CAST(@review_num AS VARCHAR))
                    EXEC ('ALTER TABLE dbo.Report ADD [Date' + @review_num + '] date, [BloodSampleID' + @review_num + '] int')
                DECLARE @update_sql VARCHAR(MAX) 
                SET @update_sql  ='UPDATE dbo.Report SET [Date' + CAST(@review_num AS VARCHAR) + '] =  CONVERT(date, ''' + CONVERT(varchar, @date, 120) + ''', 120), [BloodSampleID' + CAST(@review_num AS VARCHAR) + '] = ' + CAST(@blood_sample_id AS VARCHAR) + ' WHERE PatientID = ''' + @patient_id + ''' AND ReviewId = ' + CAST(@review_id AS varchar)
                PRINT @update_sql
                EXEC (@update_sql) 

                SET @review_num = @review_num + 1    
            END
            FETCH NEXT FROM c_reviews INTO @date, @blood_sample_id
        END

        CLOSE c_reviews
        DEALLOCATE c_reviews

    END
    FETCH NEXT FROM c_patients INTO  @patient_id, @review_id
END

CLOSE c_patients
DEALLOCATE c_patients
GO

SELECT * FROM dbo.Report