【问题标题】:Create a table with generated columns使用生成的列创建表
【发布时间】:2019-04-17 13:32:22
【问题描述】:

我们尝试用生成的列创建一个表。

请查看这些查询以了解我们当前的表结构:

嗜睡:

CREATE TABLE `Heepsy` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
  `photo_url` varchar(300) COLLATE utf8mb4_bin DEFAULT NULL,
  `followers` int(10) DEFAULT NULL,
  `engagement` decimal(5,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=51731 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

表 HypeAuditor:

CREATE TABLE `HypeAuditor` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `engaement` decimal(5,2) DEFAULT NULL,
  `Country` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `Country_percentage` int(3) DEFAULT NULL,
  `Interest1` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `Interest1_percentage` int(3) DEFAULT NULL,
  `Interest2` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `Interest2_percentage` int(3) DEFAULT NULL,
  `Interest3` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `Interest3_percentage` int(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27123 DEFAULT CHARSET=utf8;

Table NinjaOutreach:

CREATE TABLE `NinjaOutreach` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
  `fullname` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
  `photo_url` varchar(300) CHARACTER SET utf8 DEFAULT NULL,
  `followers` int(10) DEFAULT NULL,
  `engagement` decimal(5,2) DEFAULT NULL,
  `city` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `state` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `country` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `category_1` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `category_2` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `category_3` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `category_4` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `category_5` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `category_6` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=296788 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

餐桌组合:

CREATE TABLE `Kombiniert` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `fullname` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `followers_heepsy` int(11) DEFAULT NULL,
  `followers_ninjaoutreach` int(11) DEFAULT NULL,
  `followers_average` int(11) DEFAULT NULL,
  `engagement_heepsy` decimal(5,4) DEFAULT NULL,
  `engagement_ninjaoutreach` decimal(5,4) DEFAULT NULL,
  `engagement_hypeauditor` decimal(5,4) DEFAULT NULL,
  `engagement_average` decimal(5,4) DEFAULT NULL,
  `city` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `state` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `country` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `category1` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `category2` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `category3` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `category4` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `category5` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `category6` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `follower_interest1` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `follower_interest1_share` decimal(5,4) DEFAULT NULL,
  `follower_interest2` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `follower_interest2_share` decimal(5,4) DEFAULT NULL,
  `follower_interest3` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `follower_interest3_share` decimal(5,4) DEFAULT NULL,
  `follower_country` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `follower_country_share` decimal(5,4) DEFAULT NULL,
  `follower_country_total` int(11) DEFAULT NULL,
  `follower_country_engaged` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. 我们需要如何更新 SQL 查询来创建表Kombiniert,并生成以下列:

followers_average: “followers_heepsy”和“followers_ninjaoutreach”列的平均值,但前提是两者都大于 0。如果只有一列大于 0,则使用该列的值。

参与度_平均: “engagement_heepsy”、“engagement_ninjaoutreach”和“engagement_hypeauditor”列的平均值,但前提是所有列都大于 0。如果只有两列大于 0,则使用这 2 列的平均值。如果只有一列大于 0,则使用该列的值。

follower_country_total: follower_average * follower_country_share

follower_country_engaged: Followers_country_total * 参与度_平均

所有生成的列都应该是 STORED 而不是虚拟的?

  1. 我们需要如何创建一个INSERT 查询,它将执行以下操作:

    对于每个username FROM HypeAuditor 在表Kombiniert 中创建一个包含以下数据的行:

    https://docs.google.com/spreadsheets/d/1qU0WaExjg8cCsA3cdDvKf3UqdLxqXKw_8QnDRLvJwMA/edit?usp=sharing?

【问题讨论】:

  • 欢迎来到 Stack Overflow。如果您可以将表格结构和数据直接作为文本而不是超链接包含在问题中,这将对您的问题有很大帮助。
  • 也-我认为您的意思是计算列而不是生成的列。列本身似乎是固定的,但您想插入计算的聚合 - 对吗?
  • 您的表创建引用了我认为是 MySQL 的 InnoDB - 对吗?
  • 嗨@iainc 感谢您的回答。是的,它是 MySQL。

标签: mysql sql


【解决方案1】:

好的,我假设每个表中的每个用户名都有一个用户名连接和一条记录。

    INSERT INTO Kombiniert
(username, fullname, followers_heepsy, followers_ninjaoutreach, followers_average, engagement_heepsy, engagement_ninjaoutreach, engagement_hypeauditor, engagement_average, city, state, country, category1, category2, category3, category4, category5, category6, follower_interest1, follower_interest1_share, follower_interest2, follower_interest2_share, follower_interest3, follower_interest3_share, follower_country, follower_country_share, follower_country_total, follower_country_engaged)
    Select bb.*, follower_country_total*engagement_average as follower_country_engaged from
        (
            Select aa.*, followers_average*follower_country_share as follower_country_total from 
            (
                select 
                h.username,
                nj.fullname,
                hy.followers as followers_heepsy,
                nj.followers as followers_ninjaoutreach,
                case when (hy.followers=0 or hy.followers is null) and nj.followers>0 then nj.followers
                when hy.followers>0 and (nj.followers=0 or nj.followers is null) then hy.followers
                else (hy.followers+nj.followers)/2 end as followers_average,
                hy.engagement/100 as engagement_heepsy,
                nj.engagement/100 as engagement_ninjaoutreach,
                h.engagement/100 as engagement_hypeauditor,
                case    when (hy.engagement/100=0 or hy.engagement is null) and (nj.engagement/100=0 or nj.engagement is null) and h.engagement/100>0 then h.engagement/100
                        when (hy.engagement/100=0 or hy.engagement is null) and nj.engagement/100>0 and (h.engagement/100=0 or h.engagement is null) then nj.engagement/100
                        when hy.engagement/100>0  and (nj.engagement/100=0  or nj.engagement is null) and (h.engagement/100=0 or h.engagement is null) then hy.engagement/100
                        when (hy.engagement/100=0 or hy.engagement is null) and nj.engagement/100>0 and h.engagement/100>0 then (h.engagement/100+nj.engagement/100)/2
                        when hy.engagement/100>0  and nj.engagement/100>0 and (h.engagement/100=0 or h.engagement is null) then (hy.engagement/100+nj.engagement/100)/2
                        when hy.engagement/100>0  and (nj.engagement/100=0 or nj.engagement is null) and h.engagement/100>0 then (h.engagement/100+nj.engagement/100)/2
                        else (hy.engagement/100+nj.engagement/100+h.engagement/100)/3 end as engagement_average,
                nj.city,
                nj.state,
                nj.country ,
                nj.category_1,
                nj.category_2,
                nj.category_3,
                nj.category_4,
                nj.category_5,
                nj.category_6,
                h.interest1,
                h.Interest1_percentage/100 as follower_interest_share1,
                h.interest2,
                h.Interest2_percentage/100 as follower_interest_share2,
                h.interest3,
                h.Interest3_percentage/100 as follower_interest_share3,
                h.country as follower_country,
                h.country_percentage/100 as follower_country_share


                from HypeAuditor h
                left join Heepsy hy on h.username = hy.username
                left join NinjaOutreach nj on nj.username=h.username
                ) aa 
            ) bb

【讨论】:

  • 嗨@iainc 感谢您的回答!这样做我得到这个错误:Unknown column 'h.engagement' in 'field list'
  • 你在 hypeauditor 表中拼错了参与 - 我在我的版本中更正了它:-) 你有参与...
  • 谢谢,已经更新了。现在我收到以下错误:Column count doesn't match value count at row 1
  • OK - 已更新 - 忘记插入会尝试填充 ID 列。
  • 太棒了-谢谢。现在我运行查询并得到以下错误:Truncated incorrect DOUBLE value: 'Beauty & Fashion' 我认为这是因为h.interest1/100 as follower_interest_share1 因为HypeAuditor.interest1 是一个VARCHAR 列,计算的列是HypeAuditor.Interest1_percentage
【解决方案2】:

我对@ianic 的回答做了一些工作,得出了这个结果:

INSERT INTO Kombiniert
(username, fullname, followers_heepsy, followers_ninjaoutreach, followers_average, engagement_heepsy, engagement_ninjaoutreach, engagement_hypeauditor, engagement_average, city, state, country, category1, category2, category3, category4, category5, category6, follower_interest1, follower_interest1_share, follower_interest2, follower_interest2_share, follower_interest3, follower_interest3_share, follower_country, follower_country_share, follower_country_total, follower_country_engaged)
    Select bb.*, follower_country_total*engagement_average as follower_country_engaged from
        (
            Select aa.*, followers_average*follower_country_share as follower_country_total from 
            (
                select 
                h.username,
                nj.fullname,
                hy.followers as followers_heepsy,
                nj.followers as followers_ninjaoutreach,
                case when hy.followers=0 and nj.followers>0 then nj.followers
                when hy.followers>0 and nj.followers=0 then hy.followers
                else (hy.followers+nj.followers)/2 end as followers_average,
                hy.engagement/100 as engagement_heepsy,
                nj.engagement/100 as engagement_ninjaoutreach,
                h.engagement/100 as engagement_hypeauditor,
                case    when hy.engagement/100=0 and nj.engagement/100=0 and h.engagement/100>0 then h.engagement/100
                        when hy.engagement/100=0 and nj.engagement/100>0 and h.engagement/100=0 then nj.engagement/100
                        when hy.engagement/100>0 and nj.engagement/100=0 and h.engagement/100=0 then hy.engagement/100
                        when hy.engagement/100=0 and nj.engagement/100>0 and h.engagement/100>0 then (h.engagement/100+nj.engagement/100)/2
                        when hy.engagement/100>0 and nj.engagement/100>0 and h.engagement/100=0 then (hy.engagement/100+nj.engagement/100)/2
                        when hy.engagement/100>0 and nj.engagement/100=0 and h.engagement/100>0 then (h.engagement/100+nj.engagement/100)/2
                        else (hy.engagement/100+nj.engagement/100+h.engagement/100)/3 end as engagement_average,
                nj.city,
                nj.state,
                nj.country ,
                nj.category_1,
                nj.category_2,
                nj.category_3,
                nj.category_4,
                nj.category_5,
                nj.category_6,
                h.interest1,
                h.Interest1_percentage/100 as follower_interest_share1,
                h.interest2,
                h.Interest2_percentage/100 as follower_interest_share2,
                h.interest3,
                h.Interest3_percentage/100 as follower_interest_share3,
                h.country as follower_country,
                h.country_percentage/100 as follower_country_share


                from HypeAuditor h
                left join Heepsy hy on h.username = hy.username
                left join NinjaOutreach nj on nj.username=h.username
                ) aa 
            ) bb

到目前为止,它工作正常,除了一件事: HypeAuditor 中的用户名仅存在于表HeepsyNinjaOutreach 之一中。如果是这种情况,则在此特定表的列中插入了NULL,到目前为止这很好,但是计算平均值的两种情况都不起作用。

如何修改这些案例以使其也适用于这种情况?

【讨论】:

  • 再次查看我的答案 - 我已更新以添加 NULL 测试
  • 嗨@iainc - 谢谢你,问题是别的。正如我昨天发现的那样,when hy.engagement/100>0 and (nj.engagement/100=0 or nj.engagement is null) and h.engagement/100>0 then (h.engagement/100+nj.engagement/100)/2 行有一些错误,因为你检查了nj.engagement is null,但你最后是用nj.engagement 计算的。我已将平均计算更改为hy.engagement,这很好:)
  • 顺便说一句,你是否知道一些方法可以让这个查询对大表更有效,因为我的表 HeepsyHypeAuditorNinjaOutreach 有数十万行?
  • 好的,首先我会在没有 Case 语句的情况下运行查询,看看它们是否会造成巨大的问题。您还可以查看索引。您将需要每个表中的用户名上的聚集索引,然后是用户名/参与度上的一些非聚集索引。
  • 您可能还受益于先执行主插入然后运行更新查询以添加 follower_country_engaged 和 follower_country_total
【解决方案3】:

刚刚在@ianic Awesome 查询的帮助下找到了最终答案!非常感谢!

这里是:

INSERT INTO Kombiniert
(username, fullname, followers_heepsy, followers_ninjaoutreach, followers_average, engagement_heepsy, engagement_ninjaoutreach, engagement_hypeauditor, engagement_average, city, state, country, category1, category2, category3, category4, category5, category6, follower_interest1, follower_interest1_share, follower_interest2, follower_interest2_share, follower_interest3, follower_interest3_share, follower_country, follower_country_share, follower_country_total, follower_country_engaged)
    Select bb.*, follower_country_total*engagement_average as follower_country_engaged from
        (
            Select aa.*, followers_average*follower_country_share as follower_country_total from 
            (
                select 
                h.username,
                nj.fullname,
                hy.followers as followers_heepsy,
                nj.followers as followers_ninjaoutreach,
                case when hy.followers IS NULL AND nj.followers>0 THEN nj.followers
                when hy.followers>0 AND nj.followers IS NULL THEN hy.followers
                else (hy.followers+nj.followers)/2 end as followers_average,
                hy.engagement/100 as engagement_heepsy,
                nj.engagement/100 as engagement_ninjaoutreach,
                h.engagement/100 as engagement_hypeauditor,
                case    when hy.engagement IS NULL AND nj.engagement IS NULL AND h.engagement>0 THEN h.engagement/100
                        when hy.engagement IS NULL AND nj.engagement>0 AND h.engagement IS NULL THEN nj.engagement/100
                        when hy.engagement>0 AND nj.engagement IS NULL AND h.engagement IS NULL THEN hy.engagement/100
                        when hy.engagement IS NULL AND nj.engagement>0 AND h.engagement>0 THEN (h.engagement/100+nj.engagement/100)/2
                        when hy.engagement>0 AND nj.engagement>0 AND h.engagement IS NULL THEN (hy.engagement/100+nj.engagement/100)/2
                        when hy.engagement>0 AND nj.engagement IS NULL AND h.engagement>0 THEN (h.engagement/100+hy.engagement/100)/2
                        else (hy.engagement/100+nj.engagement/100+h.engagement/100)/3 end as engagement_average,
                nj.city,
                nj.state,
                nj.country ,
                nj.category_1,
                nj.category_2,
                nj.category_3,
                nj.category_4,
                nj.category_5,
                nj.category_6,
                h.interest1,
                h.Interest1_percentage/100 as follower_interest_share1,
                h.interest2,
                h.Interest2_percentage/100 as follower_interest_share2,
                h.interest3,
                h.Interest3_percentage/100 as follower_interest_share3,
                h.country as follower_country,
                h.country_percentage/100 as follower_country_share


                from HypeAuditor h
                left join Heepsy hy on h.username = hy.username
                left join NinjaOutreach nj on nj.username=h.username
                ) aa 
            ) bb

【讨论】:

    猜你喜欢
    • 2019-03-28
    • 2023-03-09
    • 2021-08-25
    • 1970-01-01
    • 2011-06-09
    • 2016-07-10
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    相关资源
    最近更新 更多