【问题标题】:Selecting values from foreign tables从外部表中选择值
【发布时间】:2017-08-09 01:20:47
【问题描述】:

我正在为 SQL INSERT 语句的 VALUES 部分处理 SELECT 子句。记录的一个字段是其他记录的外键表的外键。

鉴于: 表 - Ing_Fundamental

+----------------+-------------------+  
| ID_Fundamental | ID_Title_Category |  
+----------------+-------------------+  

表格 - Title_Category

+-------------------+----------+-------------+  
| ID_Title_Category | ID_Title | ID_Category |  
+-------------------+----------+-------------+  

表格 - 标题

+----------+-------+  
| ID_Title | Title |  
+----------+-------+  

表格 - 类别

+-------------+----------+  
| ID_Category | Category |  
+-------------+----------+  

我想选择ID_Title_Category 字段,其中Titles.Title = "Hamburger"Categories.Category = "Meat"

我的 SQL INSERT 语句:

INSERT INTO Ing_Fundamental
(
    Ing_Fundamental.ID_Title_Category
)
VALUES
(
   (SELECT ????)
)

这是 Ing_Fundamental 的 SQL CREATE TABLE 语句:

CREATE TABLE IF NOT EXISTS Ing_Fundamental
(
    ID_Fundamental INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT NOT NULL,
    ID_Title_Category INTEGER UNSIGNED,
    FOREIGN KEY fk_ID_Title_Category(ID_Title_Category)
       REFERENCES ing_title_categories(ID_Title_Category)
       ON UPDATE CASCADE
       ON DELETE RESTRICT,
    UNIQUE(ID_Title_Category)
)

我对 SELECT 语句的尝试是:

(SELECT Ing_Title_Categories.ID_Title_Category  
 FROM Ing_Title_Categories  
 WHERE (ID_Title_Category = 0))

但上述语句无法正常工作,因为ID_Title_Category 字段值不正确,必须通过查找TitlesCategories 表中的值来确定。

那么,根据TitlesCategories 表中的字段选择ID_Title_Category 字段的SQL 语法是什么?

编辑 1:背景/设计
基本成分具有唯一的 ID。
基本成分具有标题和类别。
类别是固定的(有限的)。

用户想要根据标题和类别在数据库中搜索成分。

配方包含一种或多种成分(成分 ID)。

我不记得我对 Title_Category 表的理由;它可以是规范化,也可以是减少对复合主键的需求。

我正在用 C++ 编写一个应用程序,通过 SQL 语句和查询与数据库进行交互。

在编程术语中:
Ing_Fundamental 记录包含 Title_Category 记录。
Title_Category 记录包含一个 Title 记录和一个 Category 记录。
所有记录都包含一个 ID 字段和一个或多个数据字段(例如文本)。

【问题讨论】:

  • @philipxy:我在想可能有很多成分使用共同的标题和类别,这就是为什么我将它们放在一个单独的表中。我不想复制这对。
  • @philipxy:我使用术语“嵌套”是因为我想不出合适的术语。这不是直接遏制。而不是直接的外部表引用。
  • 当我问你是否需要 ID_Title_Category 时,我想知道是否建议你阅读信息建模和关系数据库的介绍。 (如果我理解,您的问题是基本的。)我的意思是,如果 (ID_Title, ID_Category) 对是唯一的且不为空,那么该对可以是 PK 和其他 FK,您不需要 ID_Title_Category。尽管无论如何人们在这种情况下添加 id 是有原因的。
  • 什么是一些 English 语法给出模糊的“基于字段”的详细信息?
  • @philipxy:见我的 Edit1。我正在调查删除“Title_Category”表以支持复合键。

标签: mysql sql foreign-keys relational-database


【解决方案1】:

我想选择ID_Title_Category 字段,其中Titles.Title = "Hamburger"Categories.Category = "Meat"

这没有意义。大概你的意思是你想要的select ID_Title_Category from Title_Category wherecondition。但是 condition 是什么?什么是行 TitlesCategories?你不需要知道更多的 SQL 就可以这么说。

您可能的意思是您想要select ID_Title_Category from Title_Category 行,其中行(ID_Title) 位于select ID_Table from Titles where Title = 'Hamburger' 中,行(ID_Category) 位于select ID_Category from Categories where Category = 'Meat' 中。

那么知道 SQL 允许您编写 (...) in (subselect) 会很有帮助。

select ID_Title_Category
from Title_Category
where (ID_Title) in (select ID_Title from Titles where Title = 'Hamburger')
and (ID_Category) in (select ID_Category from Categories where Category = 'Meat')

或者你可能的意思是你想要select ID_Title_Category fromTitle_CategoryTC(比如)存在T.ID_TitleC.ID_Category的值,其中行T(比如)在Titles和@ 987654347@ 和行 C(比如说)在 CategoriesTC.ID_Category = C.ID_Category and C.Category = 'Meat' 中。

那么很高兴知道在 SQL 中T cross join U 是行(T.X,...,U.Y,...),其中行(T.X,...)T 中,而行(U.Y,...)U 中。 (,cross join 绑定比各种 joins 更宽松。)

select TC.ID_Title_Category
from Title_Category TC
cross join Titles T
cross join Categories C
where TC.ID_Title = T.ID_Title and T.Title = 'Hamburger'
and TC.ID_Category = C.ID_Category and C.Category = 'Meat'

另外,T cross join Ucondition 可以表示为 T join U oncondition

select TC.ID_Title_Category
from Title_Category TC
join Titles T
on TC.ID_Title = T.ID_Title and T.Title = 'Hamburger'
join Categories C
on TC.ID_Category = C.ID_Category and C.Category = 'Meat'

您可以编写另一个版本,因为在 SQL 中,当EXISTS(subselect) 时,subselect 中存在一行。

查询时我们不需要知道约束(PK、UNIQUE、FK 等)。我们确实需要每个基表行对情况的说明。然后我们可以通过基表中的行来表达结果中的行。要使用关系运算符,我们需要知道如何在谓词表达式和关系表达式之间进行转换。我们还可以通过每个结果行对情况的描述来描述结果中的行。 (这就是你如何证明直观使用 in 的合理性。)Is there any rule of thumb to construct SQL query from a human-readable description?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    相关资源
    最近更新 更多