0

我正在尝试分析一些数据。我是 SQL 新手。对此的任何帮助将不胜感激!我花了几个小时寻找解决方案,但据我所知,这种性质的大多数搜索都需要一个公用密钥,在这种情况下没有。

我在表格中有一个列,列出了受访者最喜欢的食物。

Column 1
------------------------
Banana, Tomato, Carrot 
Orange, Apple, Chicken
Peas, Potatoes, Spinach 

在单独的表格中,我按类别(水果、肉类、蔬菜等)创建了各种食物的列表,包括可能的拼写错误。例如:

Fruit
---------
Banana
Bannana
Pear
Oear

如果在第 1 列中找到来自 Fruit 列的项目,我需要将其替换为术语“fruit”。我需要对所有类别重复此操作,直到看起来像这样:

Column 1
------------------
[Fruit][Fruit][Vegetable]
[Fruit][Fruit][Meat]
[Vegetable][Vegetable][Vegetable]

我有大量数据,将来需要对其他数据重复此过程。关于如何实现这一点的任何想法?谢谢!

4

2 回答 2

1

我想我的问题是“为什么在处理后将数据保留为列表格式?”。这种格式不是正常格式

我将创建以下表格。

raw_data 
(
user_id,
food_list
)

categories
(
  food_name,
  food_category
)

processed_data
(
  user_id,
  food_category,
  food_cnt
)

hospital_data
(
  user_id,
  unknown_name
)

raw_data 表是未处理的数据。我会使用字符串拆分函数将数据解析为行。将数据转换为相同的案例并与食品类别进行比较。

任何匹配都应该被计算并保存在processed_data() 中。任何不匹配的剩余名称都应放在 hospital_data() 表中。这些是需要添加到类别表中的拼写错误条目。

该解决方案将是两次运行。

1 - 加载大部分数据。

2 - 手动将拼写错误的名称添加到类别表,重新处理 hospital_data() 表。从医院表中删除数据,并在处理数据()表中进行UPSERT(合并)数据计数。

使用元组表示法的样本数据。

raw_data 
(1, Banana, Tomato, Carrot)
(2, Orange, Apple, Chicken)
(3, Peas, Potatoes, pinach)

processed_data 
(1, Fruit, 2)
(1, Vegetable, 1)
(2, Fruit, 2)
(2, Meat, 1)
(3, Vegetable, 2)

hospital_data
(3, pinach)
于 2013-09-10T19:33:01.513 回答
0

我基于您的“第一个”问题来提出这个问题。不确定是否足以回答您的“第二个”问题:)

  1. 创建拆分函数

    create FUNCTION [dbo].[fnString_DelimeterIndex]
    (
        @Text NVARCHAR(4000),
        @Delimiter CHAR,
        @Section SMALLINT
    )
    RETURNS NVARCHAR(4000)
    AS
    
    BEGIN
        DECLARE @NextPos SMALLINT,
            @LastPos SMALLINT,
            @Found SMALLINT,
            @REVERSE BIT
    
        IF @Section < 0
            SELECT  @Text = REVERSE(@Text)--, @Section=1,@REVERSE=1
    
        SELECT  @NextPos = CHARINDEX(@Delimiter, @Text, 1),
            @LastPos = 0,
            @Found = 1
    
        WHILE @NextPos > 0 AND ABS(@Section) <> @Found
            SELECT  @LastPos = @NextPos,
                @NextPos = CHARINDEX(@Delimiter, @Text, @NextPos + 1),
                @Found = @Found + 1
    
    
        RETURN  CASE
                WHEN @Found <> ABS(@Section) OR @Section = 0 THEN NULL
                --WHEN @REVERSE =1 THEN 
                WHEN @Section > 0 THEN SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END)
                ELSE REVERSE(SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END))
            END
    END
    
  2. 选择结果,并假设您将在 column1 中有 3 个修复数据(意味着将确保每一行都有这种格式的数据 -->'data1,data2,data3')

    创建表 #Tbl (column1 varchar(50))
    创建表 #Tbl2 (category varchar(50),column1 varchar(50))

    insert into #Tbl values('Banana, Tomato, Carrot'),('Orange, Apple, Chicken'),('Peas, Potatoes, Spinach')
    
    insert into #Tbl2 values('Fruit','Banana'),('Fruit','Bananana'),('Vege','Tomato'),('Vege','Carrot')
    
    
    
    select '[' + isnull(tbl2.category,'NA') + ']' +
    '[' + isnull(tbl2_1.category,'NA') + ']' +
    '[' + isnull(tbl2_2.category ,'NA')+ ']' 
    from #Tbl tbl1
    left join #Tbl2 tbl2 ON rtrim(ltrim(dbo.fnString_DelimeterIndex(tbl1.column1,',',1))) = tbl2.column1
    left join #Tbl2 tbl2_1 ON rtrim(ltrim(dbo.fnString_DelimeterIndex(tbl1.column1,',',2))) = tbl2_1.column1
    left join #Tbl2 tbl2_2 ON rtrim(ltrim(dbo.fnString_DelimeterIndex(tbl1.column1,',',3))) = tbl2_2.column1
    
于 2013-09-10T19:52:17.120 回答