专栏名称: 人工智能头条
专注人工智能技术前沿、实战技巧及大牛心得。
目录
相关文章推荐
爱可可-爱生活  ·  【[578星]Pydoll:无需WebDri ... ·  11 小时前  
黄建同学  ·  关注//@稚晖君:明天还有惊喜,上大号发-2 ... ·  12 小时前  
黄建同学  ·  给 MCP 做的App Store 也来了 ... ·  17 小时前  
爱可可-爱生活  ·  图神经网络的统计物理学分析 查看图片 ... ·  17 小时前  
爱可可-爱生活  ·  CLT不适用于小样本LLM评估 查看图片 ... ·  昨天  
51好读  ›  专栏  ›  人工智能头条

告别手敲 SQL ?GPT-3 自动帮你写

人工智能头条  · 公众号  · AI  · 2021-02-17 09:27

正文

作者 : Brian Kane @SeekWell
编译: 伍杏玲
来源: AI科技大本营(ID: rgznai100

作为分析师,我花费大量时间编写 SQL 来回复各类业务问题,如简单的客户查询问题“用户X是否有正确的计划”,评估 KPI,增长指标“上个月有多少用户注册,转换为付费用户的百分比是多少”,预估问题“12 个月内我们将获得多少收入”。

为了让我的工作更轻松,我尽量使用自动化来完成。尽管公司研发一些工具来帮助解决,但需要写 SQL 代码的话用当前工具很难自动化,GPT-3 来救驾!

GPT-3 是一种文本完成引擎,它接受输入的文本并返回它认为接下来会出现的文本。现在已经有很多人使用它根据指定说明来生成 HTML、CSS 等代码。

由于我的大部分工作是写 SQL,所以我希望通过简单的英语描述语句,GPT-3 将这些语句转为 SQL 代码。接着 执行该 SQL,等待页面返回结果。

01


对我来说,GPT-3 Instruct(仍处于beta版)比更通用的 GPT-3 引擎更有效果,GPT-3 Instruct(尤其是davinci-instruct)可让你给出 GPT-3 响应的特定指令。下面我将详细为大家展示下一些示例,其中 gif 里输入问题由我生成,为绿色,GPT-3 将其转换为SQL(由GPT-3生成,为蓝色),我对 GPT-3 说明(黄色)和 GPT-3 示例(橙色)。
这是我给的第一条指令,一个问题以及GPT-3的回复:

说明 :给定输入问题,请使用语法正确的 PostgreSQL 进行响应。可以有创新,但 SQL 必须正确
输入 how many users signed up in the past month?
GPT-3
SELECT COUNT(*) FROM users
WHERE signup_time > now() - interval '1 month'
我没给过数据库架构,但假设我有一个名为“ users”的表,有“ signup_time”时间戳字段用于用户注册,这个符合逻辑。它知道在 PostgreSQL 中从今天的日期减去一个月的正确方法(now()-间隔“ 1个月”)。太酷了!
为了给 GPT-3 提供更多的上下文,我将有关数据库模式的信息添加到指令中。我的新指令:
说明 :给定输入问题,请使用语法正确的PostgreSQL进行响应。仅使用“用户”和“收费”的表。“用户”表具有以下列:id(整数),signup_dt(时间戳),电子邮件(字符变化)和plan_type(字符变化)。“费用”表中包含列:金额(bigint),user_id(整数)和charge_dt(时间戳)。
我问另一个问题,看看 GPT-3 是否可以根据实际数据库来响应:
输入 how much revenue did we have in the past 7 days?
GPT-3
SELECT SUM(amount) FROM charges WHERE charge_dt > now() - interval '7 days'
我向它提供了有关数据库中表和列的更多信息,它正确地推断出“ amount” =“ revenue”,并 SUM()来统计 7 天收费后的金额,我们看到,它已知道一些基本的SQL语法,并推断出我的意思。

02

用示例启动GPT-3


我想需要通过一个简单的示例来明确告知 GPT-3 表中的列,示例是提供 GPT-3上下文并充实一些细节的好方法,这有助于确定哪些列和表可以使用(GPT-3有时喜欢“发明”列)。这是我添加到提示中的示例:
输入 select all available columns from users table.
输出
SELECT id, signup_dt, email, plan_type FROM users
输入 select all available columns from charges table.
输出
SELECT amount, user_id, and charge_dt FROM charges
将这些示例提供给 GPT-3,我将再问一个问题:
输入 what was the largest payment amount made in the past 30 days?
GPT-3
SELECT MAX(amount) FROM charges WHERE charge_dt > NOW() - INTERVAL '30 days'
它知道使用MAX(金额)来获得最大的付款并正确设置日期条件,没看到有关如何从当前日期减去天数的示例。我们再试试其他的:

输入 when did user with email [email protected] make his last payment?
GPT-3
SELECT MAX(charge_dt) FROM charges WHERE user_id = 1 AND email = '[email protected]'
不太对,“收费”表中没有电子邮件列,因此该查询将失败。我也从来没有说过电子邮件=“ [email protected]”的用户的user_id = 1-不知道从何而来。要正确回答该问题,必须将“收费”表与“用户”表结合在一起,因为只有“用户”有电子邮件列。
由于知道在users.id = Charges.user_id上联接这些表是一个大的进步,所以我将给 GPT-3 一个“联接”的示例:
输入 when did jane @seekwell.io make her first payment?
输出
SELECT MIN(charge_dt) as last_payment_dt from charges LEFT JOIN
users ON users.id = charges.user_id
WHERE users.email = '[email protected]'
我再试一次:
输入 when did user with email [email protected] make his last payment?
GPT-3
SELECT MAX(charge_dt) as last_payment_dt from charges LEFT JOIN users  ON users.id = charges.user_id WHERE users.email = '[email protected]'
根据示例,它变得太简单了,它正确地更改了MIN()→MAX()并用我要求的电子邮件替换了该电子邮件。我们尝试另一个难度级别,先加更多示例来提供更多背景信息并改善响应。新的例子:
输入 how many users signed up in the past 30 days?
输出
SELECT COUNT(*) FROM users WHERE signup_dt >= now() - interval '30 days'
输入 when did user with email [email protected] sign up?
输出
SELECT signup_dt FROM users WHERE email = '[email protected]'
输入 how much revenue did we have in the past 7 days?
输出
SELECT SUM(amount) from charges WHERE charge_dt >= now() - interval '7 days'
输入 how much revenue did we have from 10-01-20 through 11-15-20?
输出
SELECT SUM(case when charge_dt>= '10-01-20'::date and charge_dt '11-15-20'::date then amount else 0 endas revenue
FROM charges
输入 how much revenue have we had from users that signed up in the last 6 months?
输出
SELECT SUM(charges.amount) FROM users INNER JOIN
charges ON users.id = charges.user_id
WHERE users.signup_dt>= now() - interval '6 months'
输入 when did user with email [email protected] make his first payment?
输出
SELECT MIN(charge_dt) as last_payment_dt from users INNER JOIN
charges ON users.id = charges.user_id
WHERE users.email = '[email protected]'
输入 how many new users signed up in each of the last 2 months?
输出
SELECT sum(case when signup_dt>= now() - interval '1 month' then 1 else 0 endas signups_this_month,
sum(case when signup_dt>= now() - interval '2 months' and signup_dt now() - interval '1 month'  then 1 else 0 endas signups_last_month
FROM users
这些示例为它提供了一些基本查询,因此它更加熟悉我的数据库以及用例的特定术语和概念(例如,“付费用户”表示其plan_type =“ pro”)。我还介绍了汇总两个日期之间的指标(收入)。我们继续加深难度:
输入 how many payments has user with email [email protected] made?
GPT-3
SELECT COUNT(*) FROM users INNER JOIN  charges ON users.id = charges.user_id WHERE users.email = '[email protected]'
GPT-3认为这里的COUNT()是适当的表达式,知道将“用户”与“收费”表结合在一起,并将电子邮件正确设置为我所询问的电子邮件。 GPT-3的另一个问题:
输入 how much revenue have we received from users with an email ending in ' seekwell.io ' in the last 3 months?
GPT-3
SELECT SUM(charges.amount) FROM  users INNER JOIN charges ON users.id = charges.user_id WHERE users.email LIKE '%seekwell.io%' AND users.signup_dt>= now() - interval '3 months'
太棒了,它知道将“以seekwell.io结尾的电子邮件”在SQL中转换为“ users.email LIKE'%seekwell.io%'”(即使之前从未见过),并对与此匹配的用户收取了所有费用的总和健康)状况。还有一个:
输入 how much revenue did we have between June 1st and August 1st 2020?
GPT-3
SELECT SUM(case when charge_dt >= '06-01-2020'::date and charge_dt '08-01-2020'::date then amount else 0 endas revenue FROM charges
我已经教过它如何从10-01-20到11-15-20来获取收入,所以它要容易一些,它确实知道将6月1日和8月1日转换为SQL中适当的日期格式('06- 01-2020”和“ 08-01-2020”)。如果它只是用“ 6月1日”和“ 8月1日”替换了我示例中的日期,我它不是在获取日期的概念,只是将模式匹配到最接近的示例。有了这个结果,我可以知道GPT-3至少在某种程度上了解了日期的概念。

03

将 GPT-3 “玩坏了”


刚才我列举的例子都是关于用户、收入和增长指标等基本问题,GPT-3 处理得很好。现在我想知道有多少用户转换为付费用户:
输入 what percent of users who signed up converted to paid?
GPT-3
SELECT COUNT() as total_users, COUNT() as total_paid_users, 100.0*(COUNT() as total_paid_users) / COUNT() as total_users AS percent_converted FROM users
这不是我想要的,绝对不是正确的SQL。它不理解“百分比”的概,它仅是 COUNT()并乘以100。我使用“百分比”来试验下:
输入 what percent of users have an email ending in ' gmail.com '?
输出
SELECT SUM(CASE WHEN email like '%gmail.com' then 1 else 0 end)/COUNT(*) as percent_gmail
FROM users
当我尝试相同的问题时,我得到:
输入 what percent of users who signed up converted to paid?
GPT-3
SELECT SUM(CASE WHEN plan_type = 'pro' THEN 1 else 0 end)/COUNT(*) as percent_paid FROM users
整洁多了,它知道将plan_type ='pro'的用户数除以用户总数即可得到我要求的百分比。我还可以向部分用户(例如最近6个月内注册的用户)询问相同的问题,并获得准确的答复:

输入 what percent of users that signed up in the past 6 months converted to paid?
GPT-3
SELECT SUM(CASE WHEN plan_type='pro' THEN 1 ELSE 0 END)/COUNT(*) AS percent_paid FROM users WHERE users.signup_dt>= now() - interval '6 months'

04

调整 GPT-3 的参数


除了给GPT-3提供指导和示例外,还可以调整参数来提高 GPT-3 的有效性。其中关键要素是“T emperature”,它 转化为GPT-3在响应中包含多少随机性。如果只需要最高的概率响应(即无随机性),则将 T emperature






请到「今天看啥」查看全文