我需要动态地将查询结果的行方式数据排列成列式结果

时间:2013-11-19 12:23:51

标签: sql sql-server stored-procedures

我有三个表countrycountrycontentlanguage,每个表的create和insert语句显示在以下脚本中(您可以通过执行以下命令直接创建和插入数据脚本)

   CREATE TABLE [dbo].[country]([id] [int] IDENTITY(1,1) NOT NULL,  [flagdeleted] [bit] NULL,
     CONSTRAINT [PK_country] PRIMARY KEY CLUSTERED 
    ([id] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY];

CREATE TABLE [dbo].[language](
    [id] [int] IDENTITY(1,1) NOT NULL,[name] [nvarchar](100) NULL,
    [code] [nchar](10) NULL,[flagdeleted] [bit] NULL,
 CONSTRAINT [PK_language] PRIMARY KEY CLUSTERED 
([id] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 

ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY];

 SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[countrycontent](
        [id] [int] IDENTITY(1,1) NOT NULL,[countryid] [int] NULL,
        [languageid] [int] NULL,[name] [nvarchar](250) NULL,[flagdeleted] [bit] NULL,
     CONSTRAINT [PK_countrycontent] PRIMARY KEY CLUSTERED 
    ([id] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 

    ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[countrycontent]  WITH CHECK ADD  CONSTRAINT [FK_countrycontent_country] 

    FOREIGN KEY([countryid])
    REFERENCES [dbo].[country] ([id])
    GO
    ALTER TABLE [dbo].[countrycontent] CHECK CONSTRAINT [FK_countrycontent_country]
    GO
    ALTER TABLE [dbo].[countrycontent]  WITH CHECK ADD  CONSTRAINT [FK_countrycontent_language] 

    FOREIGN KEY([languageid])
    REFERENCES [dbo].[language] ([id])
    GO
    ALTER TABLE [dbo].[countrycontent] CHECK CONSTRAINT [FK_countrycontent_language]
    GO

在所有表格中插入数据

 INSERT INTO country(flagdeleted) VALUES(0),(0),(0),(0),(0),(0),(0),(0);

INSERT INTO [language]([name],code,flagdeleted)
VALUES ('English','EN',0),
       ('Hindi','HI',0),('Polish','PO',0),
       ('Chinese','CH',0),('Russian','RU',0);

INSERT INTO countrycontent(countryid,languageid,flagdeleted,name) VALUES
(1,1,0,N'India'),(1,2,0,N'भारत'),(1,3,0,N'Indie'),(1,4,0,N'印度'),(1,5,0,N'Индия'),
(2,1,0,N'Australia'),(2,2,0,N'ऑस्ट्रेलिया'),(2,3,0,N'Australia'),(2,4,0,N'澳大利亚'),(2,5,0,N'Австралия'),
(3,1,0,N'China'),(3,2,0,N'चीन'),(3,3,0,N'Chiny'),(3,4,0,N'中国'),(3,5,0,N'Китай'),
(4,1,0,N'Canada'),(4,2,0,N'कनाडा'),(4,3,0,N'Kanada'),(4,4,0,N'加拿大'),(4,5,0,N'Канада'),
(5,1,0,N'Japan'),(5,2,0,N'जापान'),(5,3,0,N'Japonia'),(5,4,0,N'日本'),
(6,1,0,N'Russia'),(6,2,0,N'रूस'),(6,3,0,N'Rosja'),
(7,1,0,N'South Africa'),(7,2,0,N'दक्षिण अफ्रीका'),
 (8,1,0,N'United Kingdom'); 

我需要输出查询/存储过程,如下图所示:Image for query result


我已创建存储过程如下。


CREATE PROCEDURE GetCountryList 
AS
BEGIN
    SET NOCOUNT ON;

    SELECT c.id AS countryid, l.code languagecode , cc.NAME 
    FROM country c 
         INNER JOIN countrycontent cc ON c.id= cc.countryid AND c.flagdeleted = 0 AND cc.flagdeleted =0
         INNER JOIN [language] l ON l.id = cc.languageid AND l.flagdeleted =0
END
GO

这里确保, 没有。语言表中的语言可能会增加 国家/地区表中的国家/地区可能会增加

在这两种情况下,查询/存储过程都应该正常工作而不做任何更改。 我的意思是查询/存储过程应该是动态的。

2 个答案:

答案 0 :(得分:3)

您可以使用pivot运算符并将查询编写为:

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from [language]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT countryid,' + @cols + ' 
            from 
            (
                select cc.countryid ,cc.name as countrycontentname, [language].name as languagename
                from countrycontent cc
                inner join [language] on cc.languageid = [language].id 
            ) T 
            pivot 
            (
                max (countrycontentname)
                for languagename in (' + @cols + ')
            ) p '

execute sp_executesql @query;

答案 1 :(得分:1)

Bhavesh我想你想要这个

DECLARE @cols AS NVARCHAR(MAX),
@cols1 AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(rtrim(ltrim(code))) 
                    from [language] order by id
            FOR XML PATH(''), TYPE 
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


select @cols1 = STUFF((SELECT  'Isnull(' + QUOTENAME(rtrim(ltrim(code))) + ','''') as '  + QUOTENAME(rtrim(ltrim(code))) + ','  
                    from [language] Order by id
            FOR XML PATH(''), TYPE 
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,0,'')

Set @cols1 = Left(@cols1 , LEN(@cols1) - 1) 


set @query = 'SELECT countryid,' + @cols1 + ' 
            from 
            (
                select cc.countryid ,cc.name as countrycontentname, [language].code as languagename
                from countrycontent cc
                inner join [language] on cc.languageid = [language].id 
            ) T 
            pivot 
            (
                max (countrycontentname)
                for languagename in (' + @cols + ')
            ) p '



execute sp_executesql @query;