!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())

[Skip to main content](#__docusaurus_skipToContent_fallback)

You are viewing the **preview** v0.2 docs. View the **stable** v0.1 docs [here](/v0.1/docs/get_started/introduction/). Leave feedback on the v0.2 docs [here](https://github.com/langchain-ai/langchainjs/discussions/5386).

[

![🦜️🔗 Langchain](/v0.2/img/brand/wordmark.png)![🦜️🔗 Langchain](/v0.2/img/brand/wordmark-dark.png)

](/v0.2/)[Integrations](/v0.2/docs/integrations/platforms/)[API Reference](https://v02.api.js.langchain.com)

[More](#)

*   [People](/v0.2/docs/people/)
*   [Community](/v0.2/docs/community)
*   [Tutorials](/v0.2/docs/additional_resources/tutorials)
*   [Contributing](/v0.2/docs/contributing)

[v0.2](#)

*   [v0.2](/v0.2/docs/introduction)
*   [v0.1](https://js.langchain.com/v0.1/docs/get_started/introduction)

[🦜🔗](#)

*   [LangSmith](https://smith.langchain.com)
*   [LangSmith Docs](https://docs.smith.langchain.com)
*   [LangChain Hub](https://smith.langchain.com/hub)
*   [LangServe](https://github.com/langchain-ai/langserve)
*   [Python Docs](https://python.langchain.com/)

[Chat](https://chatjs.langchain.com)[](https://github.com/langchain-ai/langchainjs)

Search

*   [Introduction](/v0.2/docs/introduction)
*   [Tutorials](/v0.2/docs/tutorials/)
    
    *   [Build a Question Answering application over a Graph Database](/v0.2/docs/tutorials/graph)
    *   [Tutorials](/v0.2/docs/tutorials/)
    *   [Build a Simple LLM Application](/v0.2/docs/tutorials/llm_chain)
    *   [Build a Query Analysis System](/v0.2/docs/tutorials/query_analysis)
    *   [Build a Chatbot](/v0.2/docs/tutorials/chatbot)
    *   [Build an Agent](/v0.2/docs/tutorials/agents)
    *   [Build an Extraction Chain](/v0.2/docs/tutorials/extraction)
    *   [Summarize Text](/v0.2/docs/tutorials/summarization)
    *   [Tagging](/v0.2/docs/tutorials/classification)
    *   [Build a Local RAG Application](/v0.2/docs/tutorials/local_rag)
    *   [Conversational RAG](/v0.2/docs/tutorials/qa_chat_history)
    *   [Build a Retrieval Augmented Generation (RAG) App](/v0.2/docs/tutorials/rag)
    *   [Build a Question/Answering system over SQL data](/v0.2/docs/tutorials/sql_qa)
*   [How-to guides](/v0.2/docs/how_to/)
    
    *   [How-to guides](/v0.2/docs/how_to/)
    *   [How to use example selectors](/v0.2/docs/how_to/example_selectors)
    *   [Installation](/v0.2/docs/how_to/installation)
    *   [How to stream responses from an LLM](/v0.2/docs/how_to/streaming_llm)
    *   [How to stream chat model responses](/v0.2/docs/how_to/chat_streaming)
    *   [How to embed text data](/v0.2/docs/how_to/embed_text)
    *   [How to use few shot examples in chat models](/v0.2/docs/how_to/few_shot_examples_chat)
    *   [How to cache model responses](/v0.2/docs/how_to/llm_caching)
    *   [How to cache chat model responses](/v0.2/docs/how_to/chat_model_caching)
    *   [How to create a custom LLM class](/v0.2/docs/how_to/custom_llm)
    *   [How to use few shot examples](/v0.2/docs/how_to/few_shot_examples)
    *   [How to use output parsers to parse an LLM response into structured format](/v0.2/docs/how_to/output_parser_structured)
    *   [How to return structured data from a model](/v0.2/docs/how_to/structured_output)
    *   [How to add ad-hoc tool calling capability to LLMs and Chat Models](/v0.2/docs/how_to/tools_prompting)
    *   [How to create a custom chat model class](/v0.2/docs/how_to/custom_chat)
    *   [How to do per-user retrieval](/v0.2/docs/how_to/qa_per_user)
    *   [How to track token usage](/v0.2/docs/how_to/chat_token_usage_tracking)
    *   [How to track token usage](/v0.2/docs/how_to/llm_token_usage_tracking)
    *   [How to pass through arguments from one step to the next](/v0.2/docs/how_to/passthrough)
    *   [How to compose prompts together](/v0.2/docs/how_to/prompts_composition)
    *   [How to use legacy LangChain Agents (AgentExecutor)](/v0.2/docs/how_to/agent_executor)
    *   [How to add values to a chain's state](/v0.2/docs/how_to/assign)
    *   [How to attach runtime arguments to a Runnable](/v0.2/docs/how_to/binding)
    *   [How to cache embedding results](/v0.2/docs/how_to/caching_embeddings)
    *   [How to split by character](/v0.2/docs/how_to/character_text_splitter)
    *   [How to manage memory](/v0.2/docs/how_to/chatbots_memory)
    *   [How to do retrieval](/v0.2/docs/how_to/chatbots_retrieval)
    *   [How to use tools](/v0.2/docs/how_to/chatbots_tools)
    *   [How to split code](/v0.2/docs/how_to/code_splitter)
    *   [How to do retrieval with contextual compression](/v0.2/docs/how_to/contextual_compression)
    *   [How to write a custom retriever class](/v0.2/docs/how_to/custom_retriever)
    *   [How to create custom Tools](/v0.2/docs/how_to/custom_tools)
    *   [How to debug your LLM apps](/v0.2/docs/how_to/debugging)
    *   [How to load CSV data](/v0.2/docs/how_to/document_loader_csv)
    *   [How to write a custom document loader](/v0.2/docs/how_to/document_loader_custom)
    *   [How to load data from a directory](/v0.2/docs/how_to/document_loader_directory)
    *   [How to load PDF files](/v0.2/docs/how_to/document_loader_pdf)
    *   [How to load JSON data](/v0.2/docs/how_to/document_loaders_json)
    *   [How to select examples by length](/v0.2/docs/how_to/example_selectors_length_based)
    *   [How to select examples by similarity](/v0.2/docs/how_to/example_selectors_similarity)
    *   [How to use reference examples](/v0.2/docs/how_to/extraction_examples)
    *   [How to handle long text](/v0.2/docs/how_to/extraction_long_text)
    *   [How to do extraction without using function calling](/v0.2/docs/how_to/extraction_parse)
    *   [Fallbacks](/v0.2/docs/how_to/fallbacks)
    *   [Few Shot Prompt Templates](/v0.2/docs/how_to/few_shot)
    *   [How to run custom functions](/v0.2/docs/how_to/functions)
    *   [How to construct knowledge graphs](/v0.2/docs/how_to/graph_constructing)
    *   [How to map values to a database](/v0.2/docs/how_to/graph_mapping)
    *   [How to improve results with prompting](/v0.2/docs/how_to/graph_prompting)
    *   [How to add a semantic layer over the database](/v0.2/docs/how_to/graph_semantic)
    *   [How to reindex data to keep your vectorstore in-sync with the underlying data source](/v0.2/docs/how_to/indexing)
    *   [How to get log probabilities](/v0.2/docs/how_to/logprobs)
    *   [How to add message history](/v0.2/docs/how_to/message_history)
    *   [How to generate multiple embeddings per document](/v0.2/docs/how_to/multi_vector)
    *   [How to generate multiple queries to retrieve data for](/v0.2/docs/how_to/multiple_queries)
    *   [How to parse JSON output](/v0.2/docs/how_to/output_parser_json)
    *   [How to retry when output parsing errors occur](/v0.2/docs/how_to/output_parser_retry)
    *   [How to parse XML output](/v0.2/docs/how_to/output_parser_xml)
    *   [How to invoke runnables in parallel](/v0.2/docs/how_to/parallel)
    *   [How to retrieve the whole document for a chunk](/v0.2/docs/how_to/parent_document_retriever)
    *   [How to partially format prompt templates](/v0.2/docs/how_to/prompts_partial)
    *   [How to add chat history to a question-answering chain](/v0.2/docs/how_to/qa_chat_history_how_to)
    *   [How to return citations](/v0.2/docs/how_to/qa_citations)
    *   [How to return sources](/v0.2/docs/how_to/qa_sources)
    *   [How to stream from a question-answering chain](/v0.2/docs/how_to/qa_streaming)
    *   [How to construct filters](/v0.2/docs/how_to/query_constructing_filters)
    *   [How to add examples to the prompt](/v0.2/docs/how_to/query_few_shot)
    *   [How to deal with high cardinality categorical variables](/v0.2/docs/how_to/query_high_cardinality)
    *   [How to handle multiple queries](/v0.2/docs/how_to/query_multiple_queries)
    *   [How to handle multiple retrievers](/v0.2/docs/how_to/query_multiple_retrievers)
    *   [How to handle cases where no queries are generated](/v0.2/docs/how_to/query_no_queries)
    *   [How to recursively split text by characters](/v0.2/docs/how_to/recursive_text_splitter)
    *   [How to reduce retrieval latency](/v0.2/docs/how_to/reduce_retrieval_latency)
    *   [How to route execution within a chain](/v0.2/docs/how_to/routing)
    *   [How to chain runnables](/v0.2/docs/how_to/sequence)
    *   [How to split text by tokens](/v0.2/docs/how_to/split_by_token)
    *   [How to deal with large databases](/v0.2/docs/how_to/sql_large_db)
    *   [How to use prompting to improve results](/v0.2/docs/how_to/sql_prompting)
    *   [How to do query validation](/v0.2/docs/how_to/sql_query_checking)
    *   [How to stream](/v0.2/docs/how_to/streaming)
    *   [How to create a time-weighted retriever](/v0.2/docs/how_to/time_weighted_vectorstore)
    *   [How to use a chat model to call tools](/v0.2/docs/how_to/tool_calling)
    *   [How to call tools with multi-modal data](/v0.2/docs/how_to/tool_calls_multi_modal)
    *   [How to use LangChain tools](/v0.2/docs/how_to/tools_builtin)
    *   [How use a vector store to retrieve data](/v0.2/docs/how_to/vectorstore_retriever)
    *   [How to create and query vector stores](/v0.2/docs/how_to/vectorstores)
*   [Conceptual guide](/v0.2/docs/concepts)
*   Ecosystem
    
    *   [🦜🛠️ LangSmith](/v0.2/docs/langsmith/)
        
    *   [🦜🕸️LangGraph.js](/v0.2/docs/langgraph)
*   Versions
    
    *   [Overview](/v0.2/docs/versions/overview)
    *   [v0.2](/v0.2/docs/versions/v0_2)
    *   [Release Policy](/v0.2/docs/versions/release_policy)
    *   [Packages](/v0.2/docs/versions/packages)
*   [Security](/v0.2/docs/security)

*   [](/v0.2/)
*   [How-to guides](/v0.2/docs/how_to/)
*   How to deal with large databases

On this page

How to deal with large databases
================================

Prerequisites

This guide assumes familiarity with the following:

*   [Question answering over SQL data](/v0.2/docs/tutorials/sql_qa)

In order to write valid queries against a database, we need to feed the model the table names, table schemas, and feature values for it to query over. When there are many tables, columns, and/or high-cardinality columns, it becomes impossible for us to dump the full information about our database in every prompt. Instead, we must find ways to dynamically insert into the prompt only the most relevant information. Let's take a look at some techniques for doing this.

Setup[​](#setup "Direct link to Setup")
---------------------------------------

First, install the required packages and set your environment variables. This example will use OpenAI as the LLM.

    npm install langchain @langchain/community @langchain/openai typeorm sqlite3

    export OPENAI_API_KEY="your api key"# Uncomment the below to use LangSmith. Not required.# export LANGCHAIN_API_KEY="your api key"# export LANGCHAIN_TRACING_V2=true

The below example will use a SQLite connection with Chinook database. Follow these [installation steps](https://database.guide/2-sample-databases-sqlite/) to create `Chinook.db` in the same directory as this notebook:

*   Save [this](https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql) file as `Chinook_Sqlite.sql`
*   Run sqlite3 `Chinook.db`
*   Run `.read Chinook_Sqlite.sql`
*   Test `SELECT * FROM Artist LIMIT 10;`

Now, `Chinhook.db` is in our directory and we can interface with it using the Typeorm-driven `SqlDatabase` class:

    import { SqlDatabase } from "langchain/sql_db";import { DataSource } from "typeorm";const datasource = new DataSource({  type: "sqlite",  database: "../../../../Chinook.db",});const db = await SqlDatabase.fromDataSourceParams({  appDataSource: datasource,});console.log(db.allTables.map((t) => t.tableName));/**[  'Album',       'Artist',  'Customer',    'Employee',  'Genre',       'Invoice',  'InvoiceLine', 'MediaType',  'Playlist',    'PlaylistTrack',  'Track'] */

#### API Reference:

*   [SqlDatabase](https://v02.api.js.langchain.com/classes/langchain_sql_db.SqlDatabase.html) from `langchain/sql_db`

Many tables[​](#many-tables "Direct link to Many tables")
---------------------------------------------------------

One of the main pieces of information we need to include in our prompt is the schemas of the relevant tables. When we have very many tables, we can't fit all of the schemas in a single prompt. What we can do in such cases is first extract the names of the tables related to the user input, and then include only their schemas.

One easy and reliable way to do this is using OpenAI function-calling and Zod models. LangChain comes with a built-in `createExtractionChainZod` chain that lets us do just this:

    import { ChatPromptTemplate } from "@langchain/core/prompts";import {  RunnablePassthrough,  RunnableSequence,} from "@langchain/core/runnables";import { ChatOpenAI } from "@langchain/openai";import { createSqlQueryChain } from "langchain/chains/sql_db";import { SqlDatabase } from "langchain/sql_db";import { DataSource } from "typeorm";import { z } from "zod";const datasource = new DataSource({  type: "sqlite",  database: "../../../../Chinook.db",});const db = await SqlDatabase.fromDataSourceParams({  appDataSource: datasource,});const llm = new ChatOpenAI({ model: "gpt-4", temperature: 0 });const Table = z.object({  names: z.array(z.string()).describe("Names of tables in SQL database"),});const tableNames = db.allTables.map((t) => t.tableName).join("\n");const system = `Return the names of ALL the SQL tables that MIGHT be relevant to the user question.The tables are:${tableNames}Remember to include ALL POTENTIALLY RELEVANT tables, even if you're not sure that they're needed.`;const prompt = ChatPromptTemplate.fromMessages([  ["system", system],  ["human", "{input}"],]);const tableChain = prompt.pipe(llm.withStructuredOutput(Table));console.log(  await tableChain.invoke({    input: "What are all the genres of Alanis Morisette songs?",  }));/**{ names: [ 'Artist', 'Track', 'Genre' ] } */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/5ca0c91e-4a40-44ef-8c45-9a4247dc474c/r// -------------/**This works pretty well! Except, as we’ll see below, we actually need a few other tables as well.This would be pretty difficult for the model to know based just on the user question.In this case, we might think to simplify our model’s job by grouping the tables together.We’ll just ask the model to choose between categories “Music” and “Business”, and then take care of selecting all the relevant tables from there: */const prompt2 = ChatPromptTemplate.fromMessages([  [    "system",    `Return the names of the SQL tables that are relevant to the user question.  The tables are:    Music  Business`,  ],  ["human", "{input}"],]);const categoryChain = prompt2.pipe(llm.withStructuredOutput(Table));console.log(  await categoryChain.invoke({    input: "What are all the genres of Alanis Morisette songs?",  }));/**{ names: [ 'Music' ] } */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/12b62e78-bfbe-42ff-86f2-ad738a476554/r// -------------const getTables = (categories: z.infer<typeof Table>): Array<string> => {  let tables: Array<string> = [];  for (const category of categories.names) {    if (category === "Music") {      tables = tables.concat([        "Album",        "Artist",        "Genre",        "MediaType",        "Playlist",        "PlaylistTrack",        "Track",      ]);    } else if (category === "Business") {      tables = tables.concat([        "Customer",        "Employee",        "Invoice",        "InvoiceLine",      ]);    }  }  return tables;};const tableChain2 = categoryChain.pipe(getTables);console.log(  await tableChain2.invoke({    input: "What are all the genres of Alanis Morisette songs?",  }));/**[  'Album',  'Artist',  'Genre',  'MediaType',  'Playlist',  'PlaylistTrack',  'Track'] */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/e78c10aa-e923-4a24-b0c8-f7a6f5d316ce/r// -------------// Now that we’ve got a chain that can output the relevant tables for any query we can combine this with our createSqlQueryChain, which can accept a list of tableNamesToUse to determine which table schemas are included in the prompt:const queryChain = await createSqlQueryChain({  llm,  db,  dialect: "sqlite",});const tableChain3 = RunnableSequence.from([  {    input: (i: { question: string }) => i.question,  },  tableChain2,]);const fullChain = RunnablePassthrough.assign({  tableNamesToUse: tableChain3,}).pipe(queryChain);const query = await fullChain.invoke({  question: "What are all the genres of Alanis Morisette songs?",});console.log(query);/**SELECT DISTINCT "Genre"."Name"FROM "Genre"JOIN "Track" ON "Genre"."GenreId" = "Track"."GenreId"JOIN "Album" ON "Track"."AlbumId" = "Album"."AlbumId"JOIN "Artist" ON "Album"."ArtistId" = "Artist"."ArtistId"WHERE "Artist"."Name" = 'Alanis Morissette'LIMIT 5; */console.log(await db.run(query));/**[{"Name":"Rock"}] */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/c7d576d0-3462-40db-9edc-5492f10555bf/r// -------------// We might rephrase our question slightly to remove redundancy in the answerconst query2 = await fullChain.invoke({  question: "What is the set of all unique genres of Alanis Morisette songs?",});console.log(query2);/**SELECT DISTINCT Genre.Name FROM GenreJOIN Track ON Genre.GenreId = Track.GenreIdJOIN Album ON Track.AlbumId = Album.AlbumIdJOIN Artist ON Album.ArtistId = Artist.ArtistIdWHERE Artist.Name = 'Alanis Morissette' */console.log(await db.run(query2));/**[{"Name":"Rock"}] */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/6e80087d-e930-4f22-9b40-f7edb95a2145/r// -------------

#### API Reference:

*   [ChatPromptTemplate](https://v02.api.js.langchain.com/classes/langchain_core_prompts.ChatPromptTemplate.html) from `@langchain/core/prompts`
*   [RunnablePassthrough](https://v02.api.js.langchain.com/classes/langchain_core_runnables.RunnablePassthrough.html) from `@langchain/core/runnables`
*   [RunnableSequence](https://v02.api.js.langchain.com/classes/langchain_core_runnables.RunnableSequence.html) from `@langchain/core/runnables`
*   [ChatOpenAI](https://v02.api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html) from `@langchain/openai`
*   [createSqlQueryChain](https://v02.api.js.langchain.com/functions/langchain_chains_sql_db.createSqlQueryChain.html) from `langchain/chains/sql_db`
*   [SqlDatabase](https://v02.api.js.langchain.com/classes/langchain_sql_db.SqlDatabase.html) from `langchain/sql_db`

We've seen how to dynamically include a subset of table schemas in a prompt within a chain. Another possible approach to this problem is to let an Agent decide for itself when to look up tables by giving it a Tool to do so.

High-cardinality columns[​](#high-cardinality-columns "Direct link to High-cardinality columns")
------------------------------------------------------------------------------------------------

High-cardinality refers to columns in a database that have a vast range of unique values. These columns are characterized by a high level of uniqueness in their data entries, such as individual names, addresses, or product serial numbers. High-cardinality data can pose challenges for indexing and querying, as it requires more sophisticated strategies to efficiently filter and retrieve specific entries.

In order to filter columns that contain proper nouns such as addresses, song names or artists, we first need to double-check the spelling in order to filter the data correctly.

One naive strategy it to create a vector store with all the distinct proper nouns that exist in the database. We can then query that vector store each user input and inject the most relevant proper nouns into the prompt.

First we need the unique values for each entity we want, for which we define a function that parses the result into a list of elements:

    import { DocumentInterface } from "@langchain/core/documents";import { ChatPromptTemplate } from "@langchain/core/prompts";import {  RunnablePassthrough,  RunnableSequence,} from "@langchain/core/runnables";import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";import { createSqlQueryChain } from "langchain/chains/sql_db";import { SqlDatabase } from "langchain/sql_db";import { MemoryVectorStore } from "langchain/vectorstores/memory";import { DataSource } from "typeorm";const datasource = new DataSource({  type: "sqlite",  database: "../../../../Chinook.db",});const db = await SqlDatabase.fromDataSourceParams({  appDataSource: datasource,});async function queryAsList(database: any, query: string): Promise<string[]> {  const res: Array<{ [key: string]: string }> = JSON.parse(    await database.run(query)  )    .flat()    .filter((el: any) => el != null);  const justValues: Array<string> = res.map((item) =>    Object.values(item)[0]      .replace(/\b\d+\b/g, "")      .trim()  );  return justValues;}let properNouns: string[] = await queryAsList(db, "SELECT Name FROM Artist");properNouns = properNouns.concat(  await queryAsList(db, "SELECT Title FROM Album"));properNouns = properNouns.concat(  await queryAsList(db, "SELECT Name FROM Genre"));console.log(properNouns.length);/**647 */console.log(properNouns.slice(0, 5));/**[  'AC/DC',  'Accept',  'Aerosmith',  'Alanis Morissette',  'Alice In Chains'] */// Now we can embed and store all of our values in a vector database:const vectorDb = await MemoryVectorStore.fromTexts(  properNouns,  {},  new OpenAIEmbeddings());const retriever = vectorDb.asRetriever(15);// And put together a query construction chain that first retrieves values from the database and inserts them into the prompt:const system = `You are a SQLite expert. Given an input question, create a syntactically correct SQLite query to run.Unless otherwise specified, do not return more than {top_k} rows.Here is the relevant table info: {table_info}Here is a non-exhaustive list of possible feature values.If filtering on a feature value make sure to check its spelling against this list first:{proper_nouns}`;const prompt = ChatPromptTemplate.fromMessages([  ["system", system],  ["human", "{input}"],]);const llm = new ChatOpenAI({ model: "gpt-4", temperature: 0 });const queryChain = await createSqlQueryChain({  llm,  db,  prompt,  dialect: "sqlite",});const retrieverChain = RunnableSequence.from([  (i: { question: string }) => i.question,  retriever,  (docs: Array<DocumentInterface>) =>    docs.map((doc) => doc.pageContent).join("\n"),]);const chain = RunnablePassthrough.assign({  proper_nouns: retrieverChain,}).pipe(queryChain);// To try out our chain, let’s see what happens when we try filtering on “elenis moriset”, a misspelling of Alanis Morissette, without and with retrieval:// Without retrievalconst query = await queryChain.invoke({  question: "What are all the genres of Elenis Moriset songs?",  proper_nouns: "",});console.log("query", query);/**query SELECT DISTINCT Genre.NameFROM GenreJOIN Track ON Genre.GenreId = Track.GenreIdJOIN Album ON Track.AlbumId = Album.AlbumIdJOIN Artist ON Album.ArtistId = Artist.ArtistIdWHERE Artist.Name = 'Elenis Moriset'LIMIT 5; */console.log("db query results", await db.run(query));/**db query results [] */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/b153cb9b-6fbb-43a8-b2ba-4c86715183b9/r// -------------// With retrieval:const query2 = await chain.invoke({  question: "What are all the genres of Elenis Moriset songs?",});console.log("query2", query2);/**query2 SELECT DISTINCT Genre.NameFROM GenreJOIN Track ON Genre.GenreId = Track.GenreIdJOIN Album ON Track.AlbumId = Album.AlbumIdJOIN Artist ON Album.ArtistId = Artist.ArtistIdWHERE Artist.Name = 'Alanis Morissette'; */console.log("db query results", await db.run(query2));/**db query results [{"Name":"Rock"}] */// -------------// You can see a LangSmith trace of the above chain here:// https://smith.langchain.com/public/2f4f0e37-3b7f-47b5-837c-e2952489cac0/r// -------------

#### API Reference:

*   [DocumentInterface](https://v02.api.js.langchain.com/interfaces/langchain_core_documents.DocumentInterface.html) from `@langchain/core/documents`
*   [ChatPromptTemplate](https://v02.api.js.langchain.com/classes/langchain_core_prompts.ChatPromptTemplate.html) from `@langchain/core/prompts`
*   [RunnablePassthrough](https://v02.api.js.langchain.com/classes/langchain_core_runnables.RunnablePassthrough.html) from `@langchain/core/runnables`
*   [RunnableSequence](https://v02.api.js.langchain.com/classes/langchain_core_runnables.RunnableSequence.html) from `@langchain/core/runnables`
*   [ChatOpenAI](https://v02.api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html) from `@langchain/openai`
*   [OpenAIEmbeddings](https://v02.api.js.langchain.com/classes/langchain_openai.OpenAIEmbeddings.html) from `@langchain/openai`
*   [createSqlQueryChain](https://v02.api.js.langchain.com/functions/langchain_chains_sql_db.createSqlQueryChain.html) from `langchain/chains/sql_db`
*   [SqlDatabase](https://v02.api.js.langchain.com/classes/langchain_sql_db.SqlDatabase.html) from `langchain/sql_db`
*   [MemoryVectorStore](https://v02.api.js.langchain.com/classes/langchain_vectorstores_memory.MemoryVectorStore.html) from `langchain/vectorstores/memory`

We can see that with retrieval we're able to correct the spelling and get back a valid result.

Another possible approach to this problem is to let an Agent decide for itself when to look up proper nouns.

Next steps[​](#next-steps "Direct link to Next steps")
------------------------------------------------------

You've now learned about some prompting strategies to improve SQL generation.

Next, check out some of the other guides in this section, like [how to validate queries](/v0.2/docs/how_to/sql_query_checking). You might also be interested in the query analysis guide [on handling high cardinality](/v0.2/docs/how_to/query_high_cardinality).

* * *

#### Was this page helpful?

  

#### You can leave detailed feedback [on GitHub](https://github.com/langchain-ai/langchainjs/issues/new?assignees=&labels=03+-+Documentation&projects=&template=documentation.yml&title=DOC%3A+%3CPlease+write+a+comprehensive+title+after+the+%27DOC%3A+%27+prefix%3E).

[

Previous

How to split text by tokens

](/v0.2/docs/how_to/split_by_token)[

Next

How to use prompting to improve results

](/v0.2/docs/how_to/sql_prompting)

*   [Setup](#setup)
*   [Many tables](#many-tables)
*   [High-cardinality columns](#high-cardinality-columns)
*   [Next steps](#next-steps)

Community

*   [Discord](https://discord.gg/cU2adEyC7w)
*   [Twitter](https://twitter.com/LangChainAI)

GitHub

*   [Python](https://github.com/langchain-ai/langchain)
*   [JS/TS](https://github.com/langchain-ai/langchainjs)

More

*   [Homepage](https://langchain.com)
*   [Blog](https://blog.langchain.dev)

Copyright © 2024 LangChain, Inc.