Meningkatkan akurasi Text2SQL-Copen Husky (aspnetx)
Dengan ledakan model bahasa yang besar, teknologi Text2SQL (bahasa alami untuk SQL) mengubah cara kita berinteraksi dengan database. Artikel ini akan menguraikan secara sistematis metode inti untuk meningkatkan akurasi Text2SQL, yang mencakup tiga dimensi rekayasa cepat, penyesuaian model, dan inferensi. **Semua contoh didasarkan pada gudang data Microsoft AdventureWorksDW2016**.
ringkasan
Dengan ledakan model bahasa yang besar, teknologi Text2SQL (bahasa alami untuk SQL) mengubah cara kita berinteraksi dengan database. Artikel ini akan menguraikan secara sistematis metode inti untuk meningkatkan akurasi Text2SQL, yang mencakup tiga dimensi rekayasa cepat, penyesuaian model, dan inferensi.Semua contoh didasarkan pada gudang data Microsoft AdventureWorksDW2016.
Pendahuluan: Mengapa akurasi Text2SQL begitu penting?
Di era berbasis data, memungkinkan pengguna non-teknis untuk melakukan query database melalui bahasa alami adalah tugas yang sangat mahal namun juga sangat sulit. Sistem Text2SQL tradisional memiliki akurasi yang terbatas dan sulit untuk diterapkan dalam aplikasi praktis. Namun, dengan munculnya model-model hebat seperti GPT-4, Llama, dan Qwen, bidang ini telah menjadi terobosan revolusioner.
Kini, sistem industri terkemuka dapat mencapainya 82,5% akurasi eksekusi, namun bagaimana cara mencapai atau bahkan melampaui level ini dalam skenario bisnis nyata? Artikel ini akan memperluas lima dimensi inti:
- Desain dan presentasi skema – Biarkan model lebih memahami struktur database
- Kiat untuk optimasi teknik – Rancang strategi kata cepat yang efisien
- Konfigurasikan konteks bisnis – Menjembatani kesenjangan antara bahasa bisnis dan bahasa teknis
- Metode penyempurnaan model – Mengoptimalkan kemampuan model untuk tugas tertentu
- Tambahkan strategi yang masuk akal – Peningkatan akurasi selama fase inferensi
Artikel ini menggunakan pustaka sampel resmi Microsoft SQLServer dan pustaka sampel gudang data AdventureWorksDW. Saya selalu merujuk ke perpustakaan ini ketika mempelajari data warehouse. Anda dapat dengan mudah mengunduh perpustakaan ini di situs resmi Microsoft SQLServer.
1. Desain dan penyajian skema: meletakkan dasar yang baik
1.1 J-Schema: penyajian struktur database lebih bersahabat
Skema tradisional sering kali hanya menyediakan nama tabel dan nama bidang, yang tidak cukup bagi model untuk memahami semantik bisnis.J-Skema Metode berikut memberikan cara presentasi yang lebih baik:
Contoh : Tabel DimCustomer (tabel dimensi pelanggan)
表名: DimCustomer (客户维度表)
字段:
- CustomerKey (客户代理键, 主键, 自增)
- GeographyKey (地理代理键, 外键 → DimGeography.GeographyKey)
- CustomerAlternateKey (客户业务标识, 如会员编号)
- FirstName (名)
- LastName (姓)
- BirthDate (出生日期, 格式: YYYY-MM-DD)
- MaritalStatus (婚姻状态, 可选值: S-单身/M-已婚)
- Gender (性别, 可选值: M-男/F-女)
- EmailAddress (电子邮箱)
- YearlyIncome (年收入, 单位: 美元)
- TotalChildren (子女总数)
- EnglishEducation (教育程度, 可选值: Bachelors/Graduate/High School/Partial College/Partial High School)
- EnglishOccupation (职业, 如: Professional/Management/Clerical 等)
- AddressLine1 (地址第一行)
- Phone (电话号码)
- DateFirstPurchase (首次购买日期)
- CommuteDistance (通勤距离, 如: 0-1 Miles/1-2 Miles/5-10 Miles)
示例值:
- CustomerKey: 11000, 11001
- FirstName: Jon, Yang
- LastName: Yang, Zhu
- BirthDate: 1972-01-12
- MaritalStatus: S
- Gender: M
- YearlyIncome: 90000.00
- EnglishEducation: Bachelors
- EnglishOccupation: Professional
Poin penting:
- ✅ Memberikan deskripsi semantik kolom
- ✅ Menjelaskan hubungan kunci primer dan asing
- ✅ Berikan format dan nilai kolom opsional
- ✅ Memberikan data sampel (membantu model memahami karakteristik data)
1.2 Tabel manajemen hubungan asosiasi
Kueri multi-tabel adalah salah satu kesulitan Text2SQL. Menentukan hubungan tabel secara eksplisit memungkinkan model menghasilkan pernyataan GABUNG yang lebih akurat:
Asosiasi tabel inti AdventureWorksDW2016:
{
"relationships": [
{
"from_table": "FactInternetSales",
"from_column": "CustomerKey",
"to_table": "DimCustomer",
"to_column": "CustomerKey",
"relation_type": "many_to_one",
"description": "一个客户可以有多个互联网销售订单"
},
{
"from_table": "FactInternetSales",
"from_column": "ProductKey",
"to_table": "DimProduct",
"to_column": "ProductKey",
"relation_type": "many_to_one",
"description": "一个产品可以被多次销售"
},
{
"from_table": "FactInternetSales",
"from_column": "OrderDateKey",
"to_table": "DimDate",
"to_column": "DateKey",
"relation_type": "many_to_one",
"description": "订单日期关联到日期维度"
},
{
"from_table": "DimCustomer",
"from_column": "GeographyKey",
"to_table": "DimGeography",
"to_column": "GeographyKey",
"relation_type": "many_to_one",
"description": "客户关联到地理位置"
},
{
"from_table": "DimProduct",
"from_column": "ProductSubcategoryKey",
"to_table": "DimProductSubcategory",
"to_column": "ProductSubcategoryKey",
"relation_type": "many_to_one",
"description": "产品属于某个子类别"
},
{
"from_table": "DimProductSubcategory",
"from_column": "ProductCategoryKey",
"to_table": "DimProductCategory",
"to_column": "ProductCategoryKey",
"relation_type": "many_to_one",
"description": "子类别属于某个大类"
},
{
"from_table": "FactResellerSales",
"from_column": "ResellerKey",
"to_table": "DimReseller",
"to_column": "ResellerKey",
"relation_type": "many_to_one",
"description": "经销商销售关联到经销商维度"
},
{
"from_table": "FactResellerSales",
"from_column": "EmployeeKey",
"to_table": "DimEmployee",
"to_column": "EmployeeKey",
"relation_type": "many_to_one",
"description": "经销商销售关联到员工(销售代表)"
}
]
}
Jika skrip pembuatan tabel sudah berisi informasi ini, model besar dapat membantu menghasilkan informasi terkait.
2. Anjuran untuk optimasi teknik: memandu pemikiran model
2.1 Panduan Rantai Pemikiran
Pertanyaan kompleks memerlukan penalaran multi-langkah. Melalui instruksi berpikir berantai, model dipandu untuk menganalisis langkah demi langkah. Berikut adalah beberapa contoh spesifik:
Contoh: Tanyakan penjualan setiap kategori produk pada tahun 2014
问题: 查询2014年每个产品类别的总销售额,按销售额降序排列
思考过程:
1. 确定时间范围: 2014年 → DimDate.CalendarYear = 2014
2. 需要的字段: 产品类别名、销售额总计
3. 涉及的表:
- FactInternetSales (销售事实表)
- DimProduct (产品维度)
- DimProductSubcategory (产品子类别)
- DimProductCategory (产品类别)
- DimDate (日期维度)
4. 关联条件:
- FactInternetSales.ProductKey = DimProduct.ProductKey
- DimProduct.ProductSubcategoryKey = DimProductSubcategory.ProductSubcategoryKey
- DimProductSubcategory.ProductCategoryKey = DimProductCategory.ProductCategoryKey
- FactInternetSales.OrderDateKey = DimDate.DateKey
5. 聚合逻辑: 按 EnglishProductCategoryName 分组, SUM(SalesAmount) 计算总额
6. 排序: ORDER BY 总销售额 DESC
SQL:
SELECT
dc.EnglishProductCategoryName AS ProductCategory,
SUM(fis.SalesAmount) AS TotalSalesAmount
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
INNER JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
INNER JOIN DimDate dd ON fis.OrderDateKey = dd.DateKey
WHERE dd.CalendarYear = 2014
GROUP BY dc.EnglishProductCategoryName
ORDER BY TotalSalesAmount DESC;
2.2 Pustaka sampel Beberapa-Pemotretan
Untuk skenario kueri yang kompleks dan berfrekuensi tinggi, contoh SQL disediakan:
examples = [
{
"question": "查询每个产品类别的销售数量",
"sql": """
SELECT
dc.EnglishProductCategoryName,
COUNT(*) AS SalesCount
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
INNER JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
GROUP BY dc.EnglishProductCategoryName
ORDER BY SalesCount DESC;
"""
},
{
"question": "查找最近30天未下单的客户",
"sql": """
SELECT
dc.FirstName,
dc.LastName,
dc.EmailAddress
FROM DimCustomer dc
WHERE dc.CustomerKey NOT IN (
SELECT DISTINCT CustomerKey
FROM FactInternetSales
WHERE OrderDate >= DATEADD(DAY, -30, GETDATE())
);
"""
},
{
"question": "查询每个地区的销售额和订单数",
"sql": """
SELECT
dst.SalesTerritoryRegion,
dst.SalesTerritoryCountry,
COUNT(DISTINCT fis.SalesOrderNumber) AS OrderCount,
SUM(fis.SalesAmount) AS TotalSales
FROM FactInternetSales fis
INNER JOIN DimSalesTerritory dst ON fis.SalesTerritoryKey = dst.SalesTerritoryKey
GROUP BY dst.SalesTerritoryRegion, dst.SalesTerritoryCountry
ORDER BY TotalSales DESC;
"""
},
{
"question": "查询年收入前10的客户及其购买总额",
"sql": """
SELECT TOP 10
dc.FirstName,
dc.LastName,
dc.YearlyIncome,
SUM(fis.SalesAmount) AS TotalPurchases
FROM DimCustomer dc
INNER JOIN FactInternetSales fis ON dc.CustomerKey = fis.CustomerKey
GROUP BY dc.CustomerKey, dc.FirstName, dc.LastName, dc.YearlyIncome
ORDER BY dc.YearlyIncome DESC;
"""
}
]
Nilai sampel SQL:
- Bantu model “menarik kesimpulan” dan menerapkan contoh pada skenario serupa
- Standarisasi gaya SQL dan praktik terbaik
- Tingkatkan kualitas pembuatan kueri yang kompleks
2.3 Aturan kata cepat khusus
Tentukan aturan bisnis yang dapat diterapkan secara global:
全局规则:
1. 所有金额字段统一使用 money 类型,注意精度问题
2. 时间范围查询优先使用 DateKey 关联 DimDate 表
3. 产品相关查询需要考虑产品层次结构: Product → Subcategory → Category
4. 客户相关查询注意 GeographyKey 关联地理位置信息
5. 销售数据有两个来源: FactInternetSales (互联网销售) 和 FactResellerSales (经销商销售)
6. 日期字段有三种: OrderDate (下单日期), DueDate (到期日期), ShipDate (发货日期)
7. 金额计算注意货币类型: CurrencyKey 关联 DimCurrency
8. 促销活动: PromotionKey 关联 DimPromotion
3. Konfigurasi konteks bisnis: Biarkan model “mengetahui bisnisnya”
3.1 Konfigurasi terminologi: bahasa bisnis → bahasa teknis
“Pelanggan besar” sebagaimana para pebisnis menyebutnya mungkin ada dalam database YearlyIncome > 100000. Konfigurasi terminologi adalah jembatan utama:
{
"terminology": [
{
"business_term": "大客户",
"technical_mapping": "YearlyIncome > 100000",
"description": "年收入超过10万美元的客户"
},
{
"business_term": "互联网销售",
"technical_mapping": "FROM FactInternetSales",
"description": "通过网站直接销售给客户的订单"
},
{
"business_term": "经销商销售",
"technical_mapping": "FROM FactResellerSales",
"description": "通过经销商渠道的销售"
},
{
"business_term": "北美地区",
"technical_mapping": "SalesTerritoryGroup = 'North America'",
"description": "北美销售区域(美国、加拿大)"
},
{
"business_term": "欧洲地区",
"technical_mapping": "SalesTerritoryGroup = 'Europe'",
"description": "欧洲销售区域"
},
{
"business_term": "太平洋地区",
"technical_mapping": "SalesTerritoryGroup = 'Pacific'",
"description": "太平洋销售区域(澳大利亚等)"
},
{
"business_term": "自行车类产品",
"technical_mapping": "EnglishProductCategoryName="Bikes"",
"description": "自行车类别产品"
},
{
"business_term": "配件类产品",
"technical_mapping": "EnglishProductCategoryName="Accessories"",
"description": "配件类别产品"
},
{
"business_term": "服装类产品",
"technical_mapping": "EnglishProductCategoryName="Clothing"",
"description": "服装类别产品"
},
{
"business_term": "促销订单",
"technical_mapping": "PromotionKey <> 1",
"description": "参与了促销活动的订单(PromotionKey=1 表示无促销)"
}
]
}
3.2 Peningkatan deskripsi lapangan
Deskripsi bidang yang jelas lebih penting daripada nama bidang:
Contoh: Deskripsi bidang tabel FactInternetSales
-- ❌ 不好的做法(仅有字段名)
CREATE TABLE FactInternetSales(
ProductKey int,
OrderDateKey int,
CustomerKey int,
SalesAmount money,
...
);
-- ✅ 好的做法(包含详细描述)
-- 销售事实表:记录互联网销售订单明细
CREATE TABLE FactInternetSales(
ProductKey int, -- 产品代理键,关联 DimProduct
OrderDateKey int, -- 订单日期键,关联 DimDate(订单创建日期)
DueDateKey int, -- 到期日期键,关联 DimDate(应付日期)
ShipDateKey int, -- 发货日期键,关联 DimDate(实际发货日期)
CustomerKey int, -- 客户代理键,关联 DimCustomer
PromotionKey int, -- 促销代理键,关联 DimPromotion(1=无促销)
CurrencyKey int, -- 货币代理键,关联 DimCurrency
SalesTerritoryKey int, -- 销售区域代理键,关联 DimSalesTerritory
SalesOrderNumber nvarchar(20), -- 销售订单号(业务主键)
SalesOrderLineNumber tinyint, -- 订单行号(与 SalesOrderNumber 组合为主键)
RevisionNumber tinyint, -- 订单修订版本号
OrderQuantity smallint, -- 订购数量
UnitPrice money, -- 单价
ExtendedAmount money, -- 扩展金额 = UnitPrice × OrderQuantity
UnitPriceDiscountPct float, -- 单价折扣百分比
DiscountAmount float, -- 折扣金额
ProductStandardCost money, -- 产品标准成本
TotalProductCost money, -- 产品总成本
SalesAmount money, -- 销售金额(实际收入)
TaxAmt money, -- 税额
Freight money, -- 运费
CarrierTrackingNumber nvarchar(25), -- 物流跟踪号
CustomerPONumber nvarchar(25), -- 客户采购订单号
OrderDate datetime, -- 订单日期(冗余字段,便于查询)
DueDate datetime, -- 到期日期(冗余字段)
ShipDate datetime, -- 发货日期(冗余字段)
...
);
4. Model metode penyempurnaan: dari umum ke khusus
4.1 Mengapa hal ini harus diadaptasi?
Meskipun model besar umumnya kuat, model tersebut dapat digunakan untuk tugas Text2SQL pada bidang tertentu:
- Tidak memahami istilah bisnis tertentu (seperti SalesTerritoryGroup yang cocok dengan “Wilayah Pasifik”)
- SQL yang dihasilkan tidak sesuai dengan spesifikasi gudang data (misalnya lupa mengaitkan DimDate)
- Akurasi tidak memadai untuk kueri kompleks (seperti asosiasi multi-tabel, kueri hierarki)
Penyempurnaan memungkinkan model beradaptasi lebih baik terhadap skenario tertentu.
4.2 Praktik penyempurnaan DB-GPT-Hub
DB-GPT-Hub adalah proyek sumber terbuka yang berfokus pada penyempurnaan Text-to-SQL. Mengerti 78,9% akurasi eksekusi (melebihi 76,2% GPT-4).
Proses penyempurnaan (ambil AdventureWorksDW2016 sebagai contoh):
1. 数据准备
- 收集 (问题, SQL) 对,例如:
Q: "查询2014年每个产品类别的销售额"
A: "SELECT dc.EnglishProductCategoryName, SUM(fis.SalesAmount)..."
- 数据清洗和增强
* 添加同义问题("查询各产品类别的销售总额")
* 变换时间条件(2014 → 2013, 2015)
* 变换聚合维度(按类别 → 按地区、按客户)
- 划分训练集/验证集(80%/20%)
2. 模型选择
- 推荐: CodeLlama-13B 或 Qwen2.5-Coder-32B
- 量化: 4bit + LoRA 降低显存需求(可在单张 A100 上训练)
3. 训练配置
- 学习率: 2e-4
- Batch Size: 16
- Epochs: 3-5
- 最大序列长度: 2048(AdventureWorks 表名较长)
4. 评估优化
- 使用执行准确率评估(在真实数据库上执行)
- 对比语法准确率 vs 执行准确率
- 分析错误类型:表关联错误、字段错误、聚合错误等
Sampel data penyempurnaan AdventureWorksDW2016:
[
{
"question": "查询销售额最高的前10个产品",
"sql": "SELECT TOP 10 dp.EnglishProductName, SUM(fis.SalesAmount) AS TotalSales FROM FactInternetSales fis INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey GROUP BY dp.EnglishProductName ORDER BY TotalSales DESC"
},
{
"question": "查询每个国家的客户数量",
"sql": "SELECT dg.EnglishCountryRegionName, COUNT(DISTINCT dc.CustomerKey) AS CustomerCount FROM DimCustomer dc INNER JOIN DimGeography dg ON dc.GeographyKey = dg.GeographyKey GROUP BY dg.EnglishCountryRegionName ORDER BY CustomerCount DESC"
},
{
"question": "查询2014年每月的销售趋势",
"sql": "SELECT dd.EnglishMonthName, dd.MonthNumberOfYear, SUM(fis.SalesAmount) AS MonthlySales FROM FactInternetSales fis INNER JOIN DimDate dd ON fis.OrderDateKey = dd.DateKey WHERE dd.CalendarYear = 2014 GROUP BY dd.EnglishMonthName, dd.MonthNumberOfYear ORDER BY dd.MonthNumberOfYear"
}
]
Metode penyempurnaan memiliki ambang batas yang tinggi, biaya tinggi, dan siklus yang panjang, serta tidak direkomendasikan untuk proyek jangka pendek kecil dan menengah.
5. Strategi peningkatan penalaran: pilihan ganda yang optimal
5.1 Konsistensi Diri
Buat beberapa kandidat SQL dan pilih solusi optimal dengan memilih:
Contoh: Tanyakan rata-rata penjualan setiap kategori produk
问题: 查询每个产品类别的平均订单金额
候选SQL:
1.
SELECT dc.EnglishProductCategoryName, AVG(fis.SalesAmount) AS AvgAmount
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
INNER JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
GROUP BY dc.EnglishProductCategoryName;
2.
SELECT dc.EnglishProductCategoryName, AVG(fis.ExtendedAmount) AS AvgAmount
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
INNER JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
GROUP BY dc.EnglishProductCategoryName;
3.
SELECT dc.EnglishProductCategoryName, SUM(fis.SalesAmount)/COUNT(*) AS AvgAmount
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
INNER JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
GROUP BY dc.EnglishProductCategoryName;
分析:
- SQL 1 使用 SalesAmount(实际销售金额,包含折扣)
- SQL 2 使用 ExtendedAmount(扩展金额,未含折扣)
- SQL 3 手动计算平均值
投票结果:
SQL 1 和 SQL 3 语义等价 → 选择最常见的逻辑
最终选择: SQL 1(语义最清晰)
Pemungutan suara keras vs pemungutan suara lunak:
- Pemungutan suara yang sulit: pilih SQL yang paling terlihat
- Soft voting: Voting berbobot berdasarkan kesamaan hasil eksekusi (lebih baik)
5.2 MCS-SQL: Beberapa arsitektur cepat
MCS-SQL Metode tersebut diterapkan pada dataset BIRD 65,5% Akurasi, dicapai di Spider 89,6%:
proses inti:
- Beberapa generasi dengan cepat: Membuat beberapa kandidat SQL menggunakan berbagai gaya kata cepat
- Skema penyempurnaan: Filter tabel dan kolom terkait dari Skema lengkap
- skor kepercayaan diri: Evaluasi keandalan setiap kandidat SQL
- Banyak mekanisme seleksi: Pilihan solusi optimal yang lengkap
Contoh Aplikasi AdventureWorksDW2016:
问题: "查询2014年北美地区自行车类产品的销售额"
提示1(结构化):
表: FactInternetSales, DimProduct, DimProductCategory, DimSalesTerritory, DimDate
条件: CalendarYear=2014, SalesTerritoryGroup='North America', EnglishProductCategoryName="Bikes"
目标: SUM(SalesAmount)
提示2(自然语言):
从销售事实表中查询2014年的销售数据,筛选北美地区和自行车产品,计算总销售额
提示3(SQL模板):
SELECT SUM(fis.SalesAmount)
FROM FactInternetSales fis
JOIN DimDate dd ON fis.OrderDateKey = dd.DateKey
JOIN DimSalesTerritory dst ON fis.SalesTerritoryKey = dst.SalesTerritoryKey
JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
WHERE dd.CalendarYear = ?
AND dst.SalesTerritoryGroup = ?
AND dc.EnglishProductCategoryName = ?
多提示生成的候选SQL经过置信度评分和投票,选择最优解。
6. tambahkan RAG: pengetahuan domain yang disuntikkan
6.1 Mengapa RAG dibutuhkan?
Pengetahuan model besar berasal dari data pelatihan, untuk:
- Aturan bisnis internal perusahaan (seperti “PromotionKey <> 1″ untuk pesanan promosi)
- Perubahan data real-time (seperti kategori produk baru)
- Pengetahuan domain non-publik (seperti logika bisnis AdventureWorks)
Model tidak dapat diperoleh secara langsung. RAG (Retrieval Augmentation Generation) memecahkan masalah ini melalui basis pengetahuan plug-in.
6.2 Penerapan RAG di Text2SQL
Contoh Basis Pengetahuan AdventureWorksDW2016:
用户问题: "查询参与了促销活动的订单数量"
↓
检索相关文档
↓ (找到: "促销订单的 PromotionKey <> 1,PromotionKey=1 表示无促销")
注入到 Prompt
↓
模型生成 SQL:
SELECT COUNT(DISTINCT SalesOrderNumber) AS PromotionOrderCount
FROM FactInternetSales
WHERE PromotionKey <> 1;
Sebuah proses yang khas:
-
Konstruksi basis pengetahuan: Kelola aturan bisnis, definisi istilah, dan pola kueri umum
知识条目示例: - "互联网销售存储在 FactInternetSales 表" - "经销商销售存储在 FactResellerSales 表" - "产品层次: Product → Subcategory → Category" - "日期维度包含日历年度和财年两种时间维度" - "销售区域分为三大组: North America, Europe, Pacific" -
penyimpanan vektor: Gunakan vektorisasi model penyematan
-
Pencarian serupa: Mengambil dokumen yang relevan berdasarkan permintaan pengguna
-
Peningkatan cepat: Memasukkan hasil pencarian ke dalam kata-kata cepat
7. kasus praktis lengkap: SQLBot lima item konfigurasi utama
SQLBot adalah salah satu proyek Text2SQL open source terbaik di Cina yang pernah saya lihat sejauh ini. Mengambil proyek sumber terbuka SQLBot sebagai contoh, berikut adalah ringkasan singkat dari lima item konfigurasi utama yang diperlukan untuk sistem Text2SQL tingkat perusahaan:
7.1 Penjelasan detail tentang konfigurasi item (pertempuran nyata AdventureWorksDW2016)
| Item konfigurasi | memengaruhi | Contoh AdventureWorks |
|---|---|---|
| manajemen meja | Deskripsi bidang, nilai contoh | SalesAmount: 实际销售金额(含税、含运费) |
| asosiasi meja | Logika GABUNG multi-tabel | FactInternetSales.CustomerKey → DimCustomer.CustomerKey |
| Konfigurasi terminologi | Bisnis → Pemetaan Teknologi | “Produk Sepeda” = EnglishProductCategoryName="Bikes" |
| Contoh SQL | Templat kueri yang kompleks | Berikan 10-50 contoh kueri frekuensi tinggi (lihat di bawah) |
| Instruksi khusus | aturan global | “Permintaan tanggal pertama menggunakan DateKey untuk mengaitkan DimDate” |
7.2 Contoh Perpustakaan SQL AdventureWorksDW2016
-- 示例1: 按产品类别统计销售额
SELECT
dc.EnglishProductCategoryName,
COUNT(DISTINCT fis.SalesOrderNumber) AS OrderCount,
SUM(fis.SalesAmount) AS TotalSales,
AVG(fis.SalesAmount) AS AvgOrderAmount
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
INNER JOIN DimProductCategory dc ON dps.ProductCategoryKey = dc.ProductCategoryKey
GROUP BY dc.EnglishProductCategoryName
ORDER BY TotalSales DESC;
-- 示例2: 按销售区域统计年度销售趋势
SELECT
dst.SalesTerritoryGroup,
dst.SalesTerritoryCountry,
dd.CalendarYear,
SUM(fis.SalesAmount) AS YearlySales
FROM FactInternetSales fis
INNER JOIN DimSalesTerritory dst ON fis.SalesTerritoryKey = dst.SalesTerritoryKey
INNER JOIN DimDate dd ON fis.OrderDateKey = dd.DateKey
GROUP BY dst.SalesTerritoryGroup, dst.SalesTerritoryCountry, dd.CalendarYear
ORDER BY dst.SalesTerritoryGroup, dd.CalendarYear;
-- 示例3: 客户购买行为分析(RFM模型)
SELECT
dc.CustomerKey,
dc.FirstName,
dc.LastName,
MAX(fis.OrderDate) AS LastPurchaseDate,
COUNT(DISTINCT fis.SalesOrderNumber) AS PurchaseFrequency,
SUM(fis.SalesAmount) AS MonetaryValue
FROM DimCustomer dc
INNER JOIN FactInternetSales fis ON dc.CustomerKey = fis.CustomerKey
GROUP BY dc.CustomerKey, dc.FirstName, dc.LastName
ORDER BY MonetaryValue DESC;
-- 示例4: 产品销售排名(按子类别)
SELECT
dps.EnglishProductSubcategoryName,
dp.EnglishProductName,
SUM(fis.OrderQuantity) AS TotalQuantity,
SUM(fis.SalesAmount) AS TotalSales
FROM FactInternetSales fis
INNER JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey
INNER JOIN DimProductSubcategory dps ON dp.ProductSubcategoryKey = dps.ProductSubcategoryKey
GROUP BY dps.EnglishProductSubcategoryName, dp.EnglishProductName
ORDER BY dps.EnglishProductSubcategoryName, TotalSales DESC;
-- 示例5: 促销效果分析
SELECT
dp.EnglishPromotionName,
dp.EnglishPromotionType,
dp.EnglishPromotionCategory,
COUNT(DISTINCT fis.SalesOrderNumber) AS OrderCount,
SUM(fis.DiscountAmount) AS TotalDiscount,
SUM(fis.SalesAmount) AS TotalSales
FROM FactInternetSales fis
INNER JOIN DimPromotion dp ON fis.PromotionKey = dp.PromotionKey
WHERE fis.PromotionKey <> 1 -- 排除无促销的订单
GROUP BY dp.EnglishPromotionName, dp.EnglishPromotionType, dp.EnglishPromotionCategory
ORDER BY TotalSales DESC;
Kelola prioritas:
- kemampuan dasar: Manajemen tabel + asosiasi tabel (harus dikonfigurasi)
- jembatan komunikasi: Konfigurasi terminologi (bekas)
- Jawaban standar: Contoh SQL (sangat bertarget)
- aturan global: Instruksi khusus (batasan tambahan)
8. Saran praktis: Bagaimana memilih jalur optimasi?
8.1 Pilih berdasarkan adegan
| pemandangan | Metode yang direkomendasikan | Akurasi diharapkan | Contoh AdventureWorks |
|---|---|---|---|
| Kueri tabel tunggal sederhana | Contoh Beberapa Tembakan | 85%+ | SELECT * FROM DimCustomer WHERE YearlyIncome > 100000 |
| Kueri terkait multi-tabel | Menambahkan konfigurasi asosiasi skema + tabel | 80%+ | Analisis penjualan produk (3-5 tabel harus ditautkan) |
| Pertanyaan bisnis yang rumit | Terminologi Konfigurasi + Contoh SQL + RAG | 75%+ | Analisis RFM Pelanggan, analisis efek promosi |
| daerah tertentu | Model penyempurnaan | 85%+ | Cocok untuk AdventureWorks |
| persyaratan akurasi tinggi | Penyempurnaan + peningkatan waktu inferensi | 90%+ | Sistem pelaporan tingkat perusahaan |
8.2 Analisis biaya-manfaat
| tata krama | biaya pengembangan | Biaya label | Persyaratan perangkat keras | Efek yang lebih baik |
|---|---|---|---|---|
| Pekerjaan cepat | sedang | tidak ada satupun | sedang | 10-20% |
| Perbaikan skema | tengah | sedang | sedang | 5-10% |
| LAP | tengah | tengah | tengah | 5-15% |
| Model penyempurnaan | atas | atas | atas | 15-25% |
| Peningkatan alasan | tengah | tidak ada satupun | tengah | 5-10% |
Ringkasan: Peta Jalan Peningkatan Akurasi
第一阶段(快速见效)
├─ 优化 Schema 呈现(J-Schema)
├─ 添加字段描述和示例值
└─ 配置 10-20 个 Few-Shot 示例(基于 AdventureWorks)
第二阶段(深度优化)
├─ 术语配置(业务语言映射)
│ - "大客户" → YearlyIncome > 100000
│ - "北美地区" → SalesTerritoryGroup = 'North America'
├─ 表关联关系管理
│ - FactInternetSales 的所有外键关系
│ - 产品层次结构(Product → Subcategory → Category)
└─ 自定义提示词规则
- 日期查询使用 DateKey 关联 DimDate
- 产品查询考虑层次结构
第三阶段(持续改进)
├─ 构建 RAG 知识库
│ - AdventureWorks 业务规则
│ - 常见查询模式
├─ 收集反馈数据
│ - 记录用户修正的 SQL
│ - 分析错误模式
└─ 模型微调(可选)
- 使用 AdventureWorks 数据生成训练集
- 针对特定查询类型优化
第四阶段(企业级)
├─ 推理时增强(多候选投票)
├─ 权限控制
│ - 按销售区域限制数据访问
│ - 敏感字段脱敏
└─ 监控与优化
- 查询性能监控
- 准确率持续跟踪
Referensi
- Panduan Praktik Terbaik SQLBot
- MCS-SQL: Perintah ganda dan arsitektur pilihan ganda
- Akurasi Text2SQL meningkat sebesar 22,6%
- Tutorial penyempurnaan DB-GPT-Hub
- Alpha-SQL: Text2SQL bidikan nol
- Basis data sampel dokumentasi resmi AdventureWorks
PakarPBN
A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.
In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.
The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.