【发布时间】:2021-09-24 14:01:16
【问题描述】:
我是 SQL Server(版本 15)的新手,需要帮助编写 SQL。
我有一个 Invoice_Header 表,其中包含 Invoice_ID 和 Invoice_Dt 作为键:
| Invoice_ID | Invoice_Date |
|---|---|
| 1 | 1/1/2021 |
| 2 | 1/1/2021 |
| 3 | 2/1/2021 |
| 4 | 3/1/2021 |
有一个 Invoice_Detail 表,其中 Invoice_ID、Invoice_Dt、Invoice_Line 作为键以及 ID 和 Table_Name 字段。
| Invoice_ID | Invoice_Date | Invoice_Line | ID | Table_Name |
|---|---|---|---|---|
| 1 | 1/1/2021 | 1 | 2 | Food_Table |
| 1 | 1/1/2021 | 2 | 1 | Drink_Table |
| 2 | 1/1/2021 | 1 | 1 | Food_Table |
| 2 | 1/1/2021 | 2 | 3 | Drink_Table |
| 3 | 2/1/2021 | 1 | 3 | Food_Table |
| 4 | 3/1/2021 | 1 | 2 | Drink_Table |
Food_Table 有这两个字段
| ID | Food_Name |
|---|---|
| 1 | Hamburger |
| 2 | Hot Dog |
| 3 | Pasta |
Drink_Table 有这两个字段
| ID | Drink_Name |
|---|---|
| 1 | Soda |
| 2 | Milk |
| 3 | Water |
我想用这些列提取数据:
| Invoice | Invoice_Dt | Invoice_Line | Order_Name |
|---|---|---|---|
| 1 | 1/1/2021 | 1 | Hot Dog |
| 1 | 1/1/2021 | 2 | Soda |
| 2 | 1/1/2021 | 1 | Hamburger |
| 2 | 1/1/2021 | 2 | Water |
| 3 | 2/1/2021 | 1 | Pasta |
| 4 | 3/1/2021 | 1 | Milk |
因此,对于 Invoice_Detail 表中的每个发票行,它都具有 Food_Table 或 Drink_Table 的 ID 和 table_name。无论这两个表上的 ID 是什么,我都需要将 Food_Name 或 Drink_Name 作为 Order_Name。请注意,该示例仅包含这两个表。但是,它可以有多个表。因此,SQL 需要转到 invoice_detail 表上的 table_name。因此,不能硬编码 Food_Table 和 Drink_Table。
我不知道如何编写这样的 SQL,如果有人能告诉我如何编写,我将不胜感激。
谢谢
【问题讨论】:
-
你有尝试过吗?如果没有,您为什么要研究并尝试解决问题?是否可以修复设计?作为 SQL 新手,这种设计是一个非常糟糕的选择。即使对于精通该语言或 SQL 和 动态 SQL 的人来说,创建一个要求使用动态 SQL 的数据库也是一个设计缺陷。
-
数据库的设计是你的问题。你不应该有单独的表格“食物”和“饮料”。相反,您应该为所有可开票项目提供一张表格。如果您需要对单个项目进行分类,请添加一个“项目类型”字段,其中包含值“食物”和“饮料”。
-
根据您的构建在这条路径上的扩展程度,您仍然可以很容易地避免使用动态 sql。您可以使用对每个表的条件联接编写单个查询,并且只实际执行与
Invoice_Detail.Table_Name的值匹配的表的联接。或者你可以做一些事情,比如创建一个存储过程并使用像IF Table_Name = 'Food_Table' BEGIN SELECT YourColumns FROM YourTables LEFT JOIN Food_Table ON YourConditions; END;这样的流语句来有条件地运行适当的查询。 -
@Larnu。我没有创建数据库。我只是一个试图检索数据以进行报告的用户。
-
我真的建议与设计师讨论修复设计,如果我诚实的话,@user3241884。否则,您将不得不采用动态 SQL 方法,它不太可能具有高性能,并且除非您真正知道自己在做什么,否则您将在系统中引入大量安全漏洞。
标签: sql sql-server tsql dynamic-sql dynamic-tables