如何在SQLite中将不同的字段值转换为列?
我有一张这样的桌子:如何在SQLite中将不同的字段值转换为列?,sqlite,pivot-table,Sqlite,Pivot Table,我有一张这样的桌子: WidgetName | LanguageId | Text -------------------------------- lbNext | 1031 | weiter lbNext | 1033 | next btConnect | 1031 | verbinden btConnect | 1033 | connect 随着新翻译(和新语言)的添加,不同语言ID的数量也会有所不同。我想从这个表中得到
WidgetName | LanguageId | Text
--------------------------------
lbNext | 1031 | weiter
lbNext | 1033 | next
btConnect | 1031 | verbinden
btConnect | 1033 | connect
随着新翻译(和新语言)的添加,不同语言ID的数量也会有所不同。我想从这个表中得到的是另一个表,我们可以给我们的翻译。它应具有以下结构:
WidgetName | 1031 | 1033 | [...other LanguageIds]
----------------------------------------------------------
lbNext | weiter | next | [...other translations]
btConnect | verbinden | connect | [...other translations]
有没有办法通过SQL查询获得这样的表?我想问题可能在于不同语言的数量不同……这里是您需要的完整查询(我使用表1作为表名,很容易替换) 您需要以一种巧妙的方式使用PIVOT:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(LanguageId)
from Table_1
group by LanguageId
order by LanguageId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @cols
set @query = N'SELECT widgetName, ' + @cols + N' from
(
select widgetName, Text, LanguageId
from Table_1
) x
pivot
(
max(Text)
for LanguageId in (' + @cols + N')
) p '
exec sp_executesql @query;
您也可以这样做:-
Set Nocount On;
Declare @LanguageId Int
,@Sql1 Varchar(Max)
,@SqlCols Varchar(Max)
,@SqlUpdates Varchar(Max)
If Object_Id('tempdb.dbo.#WidgetLanguage') Is Not Null Drop Table #WidgetLanguage;
If Object_Id('tempdb.dbo.#Widgets') Is Not Null Drop Table #Widgets;
Create Table #WidgetLanguage
(
WidgetName Varchar(100)
,LanguageId Int
,Text Varchar(100)
)
Create Table #Widgets
(
WidgetName Varchar(100)
)
Insert Into #WidgetLanguage(WidgetName,LanguageId,Text) Values
('lbNext',1031,'weiter')
,('lbNext',1033,'next')
,('btConnect',1031,'verbinden')
,('btConnect',1033,'connect')
Select @LanguageId = Min(wl.LanguageId)
,@Sql1 = ''
,@SqlCols = ''
,@SqlUpdates = ''
From #WidgetLanguage As wl With (Nolock)
Insert Into #Widgets(WidgetName)
Select Distinct
wl.WidgetName
From #WidgetLanguage As wl With (Nolock)
;With AllLanguages As
(
Select @LanguageId As LanguageId
Union All
Select Top 1 wl.LanguageId
From (
Select Distinct
LanguageId
From #WidgetLanguage As wl With (Nolock)
) As wl
Where wl.LanguageId > @LanguageId
)
Select @Sql1 = @Sql1 + '[' + Cast(al.LanguageId As Varchar(20)) + '],'
,@SqlCols = @SqlCols + ',[' + Cast(al.LanguageId As Varchar(20)) + '] Varchar(100)'
,@SqlUpdates = @SqlUpdates + ',w.[' + Cast(al.LanguageId As Varchar(20)) + '] = Isnull(t.[' + Cast(al.LanguageId As Varchar(20)) + '],'''')'
From AllLanguages As al With (Nolock)
Select @Sql1 = Substring(@Sql1, 0, Len(@Sql1))
,@SqlCols = 'Alter Table #Widgets Add ' + Substring(@SqlCols, 2, (Len(@SqlCols) + 1))
,@SqlUpdates = Substring(@SqlUpdates, 2, (Len(@SqlUpdates) + 1))
Exec (@SqlCols)
Select @Sql1 = 'Update w Set ' + @SqlUpdates +
'From #Widgets As w ' +
'Join ' +
'(' +
'Select WidgetName,' + @Sql1 + ' From ' +
'(' +
'Select wl.WidgetName,wl.Text,wl.LanguageId '+
'From #WidgetLanguage As wl With (Nolock) '+
') As wl Pivot(Max(wl.Text) For wl.LanguageId In (' + @Sql1 + ')) t' +
') As t On w.WidgetName = t.WidgetName '
----Print (@Sql1)
Exec (@Sql1)
Select *
From #Widgets As wl With (Nolock)
这是可能的,但是,无论widgetname如何,都将使用distinct,否则,group by widget可能会改变languageId。谢谢您的回答!不幸的是,它似乎不能与SQLite一起工作。。。很抱歉我为您提供一个SQL Server解决方案…:(很抱歉,SQLite不支持DECLARE。