Eat Study Love

먹고 공부하고 사랑하라

Data Science/Research

PostgreSQL SQL2NL(5)

eatplaylove 2025. 3. 12. 19:43

LLM이 복잡한 SQL문의 경우, 아니 그렇게 복잡하지 않아도 SQL문의 From 절을 NL로 잘 표현하지 못한다.

 

솔직히, 그저 SQL문의 NL변환에 대한 학습이 잘 안 되어 있어서 이런 결과가 나왔다고 판단한다.

 

즉, 학습을 안 했을뿐 학습을 진행한다면 충분히 스스로 성능은 올릴 수 있을 것이다.

 

일단, 그 내용은 차치하고 이번에 알아볼 것은 Table 간 관계에 대해 Meta Data를 제공하면 LLM의 SQL2NL 번역 정확도는 상승할 것인가..?

 

당연히 기존보단 상승할 것으로 보인다.

 

앞선 20개의 Sample가지고 지속적으로 실험을 진행해보자.

 

Meta data는 구해놨다. California_school DB의 Table간 FK/PK 관계와, 각 Table의 Column에 대한 설명을 추가했다.

Column 설명은 Column 명, Description, Samples, Value Description으로 구성했다.

 

ex)

  - Column: AvgScrMath (INTEGER)
    - Description: #The average scores in Math column in the sat scores table of the california_schools database represents the average SAT Math scores of students in each school. 
    - Samples: [418, 546, 387, None, 590]
    - Value Description: average scores in Math

Table Col 수가 많다보니까, Metadata 용량이 꽤나 크다..

 

그리고 Bird Dev는 SQLite 이고, 내 실험환경은 PostgreSQL이라 SQL Syntax가 약간 다르다.

이건 GPT를 통해 아래처럼 일일히 정정해줬다. 노가다..

PSQL Ver SQL Gold SQL
SELECT "Free Meal Count (Ages 5-17)" / "Enrollment (Ages 5-17)"
FROM frpm
WHERE "Educational Option Type" = 'Continuation School'
AND ("Free Meal Count (Ages 5-17)" / "Enrollment (Ages 5-17)") IS NOT NULL
ORDER BY "Free Meal Count (Ages 5-17)" / "Enrollment (Ages 5-17)" ASC
LIMIT 3
SELECT `Free Meal Count (Ages 5-17)` / `Enrollment (Ages 5-17)` FROM frpm WHERE `Educational Option Type` = 'Continuation School' AND `Free Meal Count (Ages 5-17)` / `Enrollment (Ages 5-17)` IS NOT NULL ORDER BY `Free Meal Count (Ages 5-17)` / `Enrollment (Ages 5-17)` ASC LIMIT 3
SELECT T2."phone"
FROM frpm AS T1
INNER JOIN schools AS T2
ON T1."cdscode" = T2."cdscode"
WHERE T1."Charter Funding Type" = 'Directly funded'
AND T1."Charter School (Y/N)" = 1
AND T2."opendate" > '2000-01-01'
SELECT T2.Phone FROM frpm AS T1 INNER JOIN schools AS T2 ON T1.CDSCode = T2.CDSCode WHERE T1.`Charter Funding Type` = 'Directly funded' AND T1.`Charter School (Y/N)` = 1 AND T2.OpenDate > '2000-01-01'
SELECT T1."school", T1."street"
FROM schools AS T1
INNER JOIN frpm AS T2
  ON T1."cdscode" = T2."cdscode"
WHERE T2."Enrollment (K-12)" - T2."Enrollment (Ages 5-17)" > 30;
SELECT T1.School, T1.Street FROM schools AS T1 INNER JOIN frpm AS T2 ON T1.CDSCode = T2.CDSCode WHERE T2.`Enrollment (K-12)` - T2.`Enrollment (Ages 5-17)` > 30
SELECT T2."School Name"
FROM satscores AS T1
INNER JOIN frpm AS T2
  ON T1."cds" = T2."cdscode"
WHERE (T2."Free Meal Count (K-12)" / T2."Enrollment (K-12)") > 0.1
  AND T1."numge1500" > 0;
SELECT T2.`School Name` FROM satscores AS T1 INNER JOIN frpm AS T2 ON T1.cds = T2.CDSCode WHERE CAST(T2.`Free Meal Count (K-12)` AS REAL) / T2.`Enrollment (K-12)` > 0.1 AND T1.NumGE1500 > 0

 

일단 Sample을 20개 정도로 적게 갖고 놀다보니까 일일히 DB Schema와 Parsing Info 등을 수작업으로 LLM에 입력시켜서 NL Output을 뽑아내봤다.. 이렇다할 특이점은 없는 거 같다..ㅠ

 

Predicted Text Predicted Text ( + DB Schema metadata ) Predicted Text ( + Metadata, Parsing info)
Retrieve the ratio of "Free Meal Count (Ages 5-17)" to "Enrollment (Ages 5-17)" from the frpm table for "Continuation Schools," filtering out null values and sorting in ascending order, returning the top 3 results. Retrieve the ratio of students receiving free meals to total enrolled students (ages 5-17) for schools classified as "Continuation School," excluding null values, and return the top 3 schools with the lowest ratio. Retrieve the ratio of Free Meal Count (Ages 5-17) to Enrollment (Ages 5-17) from the frpm table for schools classified as Continuation School, excluding null values, and return the top 3 schools with the lowest ratio.

 

Metadata 또는 Parsing info가 제대로 LLM에 적용된 거 같지가 않다.

그렇지 않고서야 이렇게 차이가 없을 수가 있을까..

 

원활히 진행중인 NL2SQL에서 Prompt Engineering을 어떻게 진행하는지 확인하고, 다시 이와 유사하게 SQL2NL Prompt Engineering을 진행해봐야겠다.