ai写出相关的业务sql
1个非常典型且实用的场景用AI快速生成保险业务的核心表结构及关联查询SQL。这不仅是你日常工作的真实需求也是你向面试官展示“我知道怎么用AI生成业务代码并且能验证它”的绝佳案例。以下是一套简化的保险业务核心表结构涵盖了客户、保单和账户这三个最核心的主题域。1. 客户信息表 (customer)记录投保人/被保险人的基本信息。sqlCREATE TABLE customer ( cust_id VARCHAR(20) PRIMARY KEY, -- 客户ID唯一标识 cust_name VARCHAR(50) NOT NULL, -- 客户姓名 id_type VARCHAR(10) DEFAULT ID_CARD, -- 证件类型ID_CARD身份证/PASSPORT护照 id_number VARCHAR(30) UNIQUE, -- 证件号码 gender CHAR(1) CHECK (gender IN (M, F)), -- 性别M男/F女 birth_date DATE, -- 出生日期 mobile VARCHAR(15), -- 手机号码 email VARCHAR(50), -- 电子邮箱 address VARCHAR(200), -- 联系地址 create_time TIMESTAMP DEFAULT NOW() -- 创建时间 ); -- 添加注释 COMMENT ON TABLE customer IS 客户信息表; COMMENT ON COLUMN customer.cust_id IS 客户ID主键; COMMENT ON COLUMN customer.cust_name IS 客户姓名; COMMENT ON COLUMN customer.id_number IS 证件号码唯一索引;2. 保单主表 (policy)记录每一份保险合同的详细信息。sqlCREATE TABLE policy ( policy_no VARCHAR(30) PRIMARY KEY, -- 保单号核心业务主键 cust_id VARCHAR(20) NOT NULL, -- 投保人客户ID insured_cust_id VARCHAR(20), -- 被保险人客户ID product_code VARCHAR(20) NOT NULL, -- 保险产品编码如ENDOW_20Y premium DECIMAL(18,2) NOT NULL, -- 保费金额元 sum_insured DECIMAL(18,2) NOT NULL, -- 保险金额元 policy_status VARCHAR(10) DEFAULT ACTIVE, -- 保单状态ACTIVE生效/SURRENDER退保/EXPIRED满期 effective_date DATE NOT NULL, -- 生效日期 expiry_date DATE, -- 满期/终止日期 payment_term VARCHAR(10) DEFAULT ANNUAL, -- 缴费方式ANNUAL年缴/MONTHLY月缴/SINGLE趸缴 create_time TIMESTAMP DEFAULT NOW(), -- 创建时间 update_time TIMESTAMP, -- 更新时间 FOREIGN KEY (cust_id) REFERENCES customer(cust_id) -- 关联投保人 ); -- 添加注释 COMMENT ON TABLE policy IS 保单主表; COMMENT ON COLUMN policy.policy_no IS 保单号业务主键; COMMENT ON COLUMN policy.cust_id IS 投保人客户ID关联customer表; COMMENT ON COLUMN policy.insured_cust_id IS 被保险人客户ID; COMMENT ON COLUMN policy.premium IS 保费金额单位元; COMMENT ON COLUMN policy.policy_status IS 保单状态ACTIVE生效/SURRENDER退保/EXPIRED满期;3. 账户交易流水表 (account_transaction)记录与保单相关的资金账户变动明细如保费缴纳、退保金支付等。sqlCREATE TABLE account_transaction ( trans_id BIGSERIAL PRIMARY KEY, -- 交易流水号自增 policy_no VARCHAR(30) NOT NULL, -- 关联的保单号 trans_type VARCHAR(20) NOT NULL, -- 交易类型PREMIUM_PAY缴费/CLAIM_PAY理赔款/SURRENDER_REFUND退保金 trans_amount DECIMAL(18,2) NOT NULL, -- 交易金额正数收入/负数支出 trans_date DATE NOT NULL, -- 交易日期 trans_status VARCHAR(10) DEFAULT SUCCESS, -- 交易状态SUCCESS成功/FAIL失败 counterparty VARCHAR(100), -- 交易对手如银行名称 create_time TIMESTAMP DEFAULT NOW(), -- 创建时间 FOREIGN KEY (policy_no) REFERENCES policy(policy_no) -- 关联保单表 ); -- 添加注释 COMMENT ON TABLE account_transaction IS 账户交易流水表; COMMENT ON COLUMN account_transaction.trans_id IS 交易流水号自增主键; COMMENT ON COLUMN account_transaction.trans_type IS 交易类型PREMIUM_PAY缴费/CLAIM_PAY理赔款/SURRENDER_REFUND退保金;二、核心关联查询 SQL含中文注释需求查询某位客户的保单摘要及账户流水sql-- 查询客户CUST001的保单摘要及账户流水信息 SELECT -- 客户基础信息 c.cust_id AS 客户ID, c.cust_name AS 客户姓名, c.id_number AS 证件号码, c.mobile AS 手机号, -- 保单核心信息 p.policy_no AS 保单号, p.product_code AS 产品编码, p.premium AS 保费金额, p.sum_insured AS 保额, p.policy_status AS 保单状态, p.effective_date AS 生效日期, p.expiry_date AS 满期日期, -- 账户流水信息 t.trans_id AS 交易流水号, t.trans_type AS 交易类型, t.trans_amount AS 交易金额, t.trans_date AS 交易日期, t.counterparty AS 交易对手 FROM customer c -- 通过客户ID关联保单表左连接 LEFT JOIN policy p ON c.cust_id p.cust_id -- 通过保单号关联交易流水表左连接 LEFT JOIN account_transaction t ON p.policy_no t.policy_no WHERE c.cust_id CUST001 -- 指定客户ID ORDER BY p.effective_date DESC, -- 按生效日期降序排列最近投保的在前 t.trans_date DESC; -- 同一保单下按交易日期降序排列最新交易在前有可能有的客户 没有保单信息吗 所以用 policy left join customer 然后 left join account_transaction 是不是更好一、两种写法的本质区别你的写法AI原来的写法区别policy LEFT JOIN customercustomer LEFT JOIN policy一个是以保单为主一个是以客户为主先看保单再补客户信息先看客户再补保单信息核心差异在于“谁是主表”以policy为主表的意思展示所有保单不管保单有没有对应的客户信息虽然保险业务中不太可能出现没有客户的保单但理论上确实存在数据质量问题或孤儿单如果某个保单的客户信息缺失客户字段显示NULL但保单本身会显示出来以customer为主表的意思展示所有客户不管客户有没有买过保险如果客户没有保单保单和交易字段都是NULL客户本身会显示出来二、为什么policy LEFT JOIN customer在“查询保单及流水”场景下更合理场景推荐写法原因查询保单及流水policy LEFT JOIN customer需求重点是保单客户信息是用来补充保单的不应该让没有保单的客户出现查询客户及其保单customer LEFT JOIN policy需求重点是客户想查看客户资产全貌即使没有保单也要显示客户做客户画像/360视图customer LEFT JOIN policy要看到所有客户包括没有购买记录的出报表/监管报送policy LEFT JOIN customer监管报送的是保单数据客户信息是辅助字段一个保单对应一个客户三、如果按你的思路重构SQLsql-- 查询某张保单的详细信息及流水记录 SELECT -- 保单信息主表 p.policy_no AS 保单号, p.product_code AS 产品编码, p.premium AS 保费金额, p.policy_status AS 保单状态, p.effective_date AS 生效日期, -- 客户信息从表左补 c.cust_name AS 客户姓名, c.mobile AS 手机号, -- 流水信息从表左补 t.trans_id AS 交易流水号, t.trans_type AS 交易类型, t.trans_amount AS 交易金额, t.trans_date AS 交易日期 FROM policy p LEFT JOIN customer c ON p.cust_id c.cust_id LEFT JOIN account_transaction t ON p.policy_no t.policy_no WHERE p.policy_no POL001 -- 指定保单号 ORDER BY t.trans_date DESC;四、面试时如何把“发现这个问题”变成加分项如果面试官问“你怎么验证AI生成的SQL是正确的”你可以这样说“我会先关注关联逻辑。比如这个查询保单的需求AI一开始写的是customer LEFT JOIN policy我看一眼觉得不太对——这个写法会把所有客户都查出来包括没有买过保险的客户。但业务需求是‘查保单的明细和流水’主表应该是保单而不是客户。所以我改成了policy LEFT JOIN customer这样展示的是所有保单客户信息作为辅助字段补充进来交易流水也通过保单号关联。这个细节看起来不大但能反映对业务需求的理解深度——是用保单驱动查询还是用客户驱动查询取决于业务场景。”这个回答向面试官传递了三个信息面试官接收到什么原因“他能发现AI代码中的问题”他有验证习惯不是无脑信任AI“他理解业务逻辑和数据模型的关系”知道主表选择取决于业务需求“他写SQL有经验”这种关联顺序的判断是长年写SQL形成的手感五、补充什么情况下用customer LEFT JOIN policy如果需求是“查询客户360视图”目的是了解客户的整体情况那确实应该用客户作主表sqlSELECT c.cust_id, c.cust_name, p.policy_no, p.premium, p.policy_status FROM customer c LEFT JOIN policy p ON c.cust_id p.cust_id WHERE c.cust_id CUST001;这个写法会把客户的基本信息显示出来不管他有没有保单。如果客户还没有购买任何保险保单字段为NULL但这本身就是一种有价值的信息——说明这个客户还是“潜在客户”或者有销售跟进的空间。六、总结你的发现是否合理面试时怎么说“AI用customer LEFT JOIN policy不太对应该用policy LEFT JOIN customer”✅非常合理说明你理解业务驱动表的选择逻辑“我根据业务需求判断主表应该是保单而非客户”“查询保单及流水主表选policy更合理”✅完全正确展示保单数据时保单是核心实体“用保单做驱动查询不会因为客户维度信息缺失而导致保单数据丢失”“如果是客户360视图才应该用客户做主表”✅体现了你对不同业务场景的区分能力“不同场景选不同的主表取决于查询的核心实体是什么”这个细节能很好地体现你的SQL功底和业务理解面试时如果能主动说出来会成为加分项。为什么policy做主表更常见1. 保险公司的核心业务实体是“保单”不是“客户”保险公司卖的是“保单”不是“客户关系”。保费收入、准备金计提、理赔支出、监管报送——所有核心业务指标都围绕保单展开。客户只是一个维度用来描述“这张保单是谁买的”。业务场景主表说明保费收入统计policy统计的是“保单的保费”不是“客户的保费”监管报送EASTpolicy报送的是“保单级明细”不是“客户级汇总”准备金计算policy每张保单的未到期责任准备金、未决赔款准备金理赔分析policy claim理赔是保单的“后续事件”保单是根客户360视图customer只有这一个场景是以客户为主所以保险数据开发团队天然形成了“保单驱动”的思维习惯。2. 保单维度的业务需求远多于客户维度保险公司的日常数据需求按出现频率排序大概是这样的需求类型频率主表保单明细查询⭐⭐⭐⭐⭐policy保费收入日报/月报⭐⭐⭐⭐⭐policy渠道业绩统计⭐⭐⭐⭐policy退保率分析⭐⭐⭐⭐policy续期率分析⭐⭐⭐⭐policy监管报送数据提取⭐⭐⭐⭐policy客户投诉分析⭐⭐⭐customer客户画像/分群⭐⭐customer客户资产排名⭐⭐customer结论客户需求是保单需求的子集主表选policy能覆盖90%以上的业务场景。二、保险行业的数据模型本身也是保单驱动的你之前接触过的Teradata FS-LDM保险行业数据模型的核心设计逻辑是主题域核心实体说明保单主题保单Policy所有保费、准备金、佣金都挂在保单上客户主题客户Party作为保单的参与者角色投保人、被保人、受益人产品主题产品Product保单关联的产品定义收付主题收付费Transaction保单发生的资金变动FS-LDM 的“保单主题”是所有主题域中最核心的因为监管报送、财务核算、风险管理都依赖保单级数据。在实际生产中你在保险行业写SQL90%以上的查询起点就是policy。这几乎是一个行业默认规则相当于“保险数据开发的默认起手式”。如果你面试时能说出“保险数据开发默认是从保单表开始的这是行业习惯也是业务驱动的结果”面试官就会知道你是真正在保险数据领域待过的。三、如果面试官追问“为什么不用客户做主表”你可以这样回答“在保险行业客户是保单的一个维度字段不是业务主体。比如查保费收入按客户维度汇总没有意义——因为客户可能有趸缴、期缴、退保等多个保单数据口径很难定义。保单是业务发生的最小粒度每笔保费、每笔佣金、每笔准备金都挂在保单上所以报表和监管报送都从保单出发。用customer做主表只有一种场景就是做客户360视图的时候想了解客户整体持有情况。但这种查询频率很低属于专题分析不是日常报表。日常开发以保单驱动是更常见也更自然的写法。”要点这个回答包含了行业逻辑保单是业务主体、技术视角最小粒度和场景区分日常报表 vs 专题分析听起来既专业又有经验。