我有一个包含单词列表和相关wordForms的表.表中的典型数据如下所示.请注意,WordForms的某些列结束,例如,有些只是以最后一个wordform字结束
Id Word WordForms
1 abandon abandoned, abandoning, abandonment, abandons
2 abstract abstraction, abstractions, abstractly, abstracts, e.g.
Run Code Online (Sandbox Code Playgroud)
这是源数据表的布局:
CREATE TABLE [dbo].[TempWords]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[Word] NVARCHAR (MAX) NOT NULL,
[WordForms] NVARCHAR (MAX) NULL,
)
Run Code Online (Sandbox Code Playgroud)
我想用这些数据来填充两个表.我知道使用SQL INSERT INTO,但我认为只能帮助我使用一个表.我想要做的是取第一个Word,将其放入Words表中,然后将现在用逗号分隔的字形分开,并将它们放入WordForms表中.
CREATE TABLE [dbo].[Words]
(
[WordId] INT IDENTITY (1, 1) NOT NULL,
[Word] NVARCHAR (MAX) NOT NULL
)
CREATE TABLE [dbo].[WordForms]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[WordId] INT NOT NULL,
[Text] NVARCHAR (MAX) NULL,
)
Run Code Online (Sandbox Code Playgroud)
谁能给我一些关于如何做到这一点的提示?
首先,您可以创建UDF函数来分隔CSV值.
CREATE FUNCTION dbo.fn_Split (
@InputString VARCHAR(8000),
@Delimiter VARCHAR(50)
)
RETURNS @Items TABLE (
Item VARCHAR(8000)
)
AS
BEGIN
IF @Delimiter = ' '
BEGIN
SET @Delimiter = ','
SET @InputString = REPLACE(@InputString, ' ', @Delimiter)
END
IF (@Delimiter IS NULL OR @Delimiter = '')
SET @Delimiter = ','
--INSERT INTO @Items VALUES (@Delimiter) -- Diagnostic
--INSERT INTO @Items VALUES (@InputString) -- Diagnostic
DECLARE @Item VARCHAR(8000)
DECLARE @ItemList VARCHAR(8000)
DECLARE @DelimIndex INT
SET @ItemList = @InputString
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
WHILE (@DelimIndex != 0)
BEGIN
SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
INSERT INTO @Items VALUES (@Item)
-- Set @ItemList = @ItemList minus one less item
SET @ItemList = SUBSTRING(@ItemList, @DelimIndex+1, LEN(@ItemList)-@DelimIndex)
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
END -- End WHILE
IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
BEGIN
SET @Item = @ItemList
INSERT INTO @Items VALUES (@Item)
END
-- No delimiters were encountered in @InputString, so just return @InputString
ELSE INSERT INTO @Items VALUES (@InputString)
RETURN
END -- End Function
GO
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用下面的INSERT语句来填充表.
INSERT INTO [Words]
SELECT Word FROM TempWords
INSERT INTO WordForms
SELECT
W.WordId,
LTRIM(RTRIM(FNT.Item)) AS Item
FROM TempWords AS TW
INNER JOIN [Words] AS W
ON TW.[Word]=W.[Word]
CROSS APPLY fn_Split(REPLACE(TW.WordForms,', e.g.',''),',') AS FNT
SELECT * FROM [Words]
SELECT * FROM WordForms
Run Code Online (Sandbox Code Playgroud)
您可以将单词插入到第一个表中,而不是解析单词表单,并将它们插入到子表中,并链接到父表.
链接到父表可以通过加入word列(我猜它是唯一的)或通过做一些MERGE + OUTPUT事情来获得一步SOURCE.ID(来自@words_csv)和INSERTED.ID.你喜欢什么方式.
解析也可以通过多种方式实现,请查看此示例(实际上我不建议使用sql进行解析).
DECLARE @words_csv TABLE (Id INT IDENTITY(1, 1), Word VARCHAR(100), WordForms VARCHAR(1000))
INSERT INTO @words_csv(word, wordforms)
VALUES
('abandon', 'abandoned, abandoning, abandonment, abandons, e.g.'),
('abstract', 'abstraction, abstractions, abstractly, abstracts')
--INSERT INTO [dbo].[Words](word)
--SELECT w.word
--FROM @words_csv w
;WITH word_forms_extracted AS
(
SELECT w.id,
w.word,
ltrim(rtrim(cast(case when CHARINDEX(',', w.WordForms) > 0 then substring(w.wordforms, 1, CHARINDEX(',', w.WordForms)-1) end AS VARCHAR(1000)))) wordform,
stuff(w.wordforms, 1, CHARINDEX(',', w.WordForms), '') wordforms
FROM @words_csv w
UNION ALL
SELECT w.id,
w.word,
ltrim(rtrim(cast(case when CHARINDEX(',', wfe.WordForms) > 0 then substring(wfe.wordforms, 1, CHARINDEX(',', wfe.WordForms)-1) else wfe.wordforms end AS VARCHAR(1000)))) wordform,
case when CHARINDEX(',', wfe.WordForms) > 0 then stuff(wfe.wordforms, 1, CHARINDEX(',', wfe.WordForms), '') ELSE '' end wordforms
FROM @words_csv w
INNER JOIN word_forms_extracted wfe
ON wfe.id = w.id
WHERE wfe.wordforms != ''
)
SELECT wf.id, wf.word, wf.wordform
FROM word_forms_extracted wf
--INNER JOIN [dbo].[Words] w
--ON w.word = wf.word
WHERE wf.wordform NOT IN ('', 'e.g.')
ORDER BY wf.id, wf.wordform
OPTION(MAXRECURSION 1000)
Run Code Online (Sandbox Code Playgroud)
通过加入列可以看到最终SELECT可以轻松修改为INSERT INTO dbo.WordForms (...) SELECT ...
链接到dbo.Words此处word.
| 归档时间: |
|
| 查看次数: |
587 次 |
| 最近记录: |