简体   繁体   English

如何通过给定的超级表在SQL主键识别子类型表

[英]how identify subtype table by given primary key of super table in sql

I have 3 tables product, CD, OtherProduct 我有3表产品,CD,其他产品

product is super table and CD, OtherProduct are sub types of product and has primary key of product as foreign key in it. product是超级表和CD,OtherProduct是产品的子类型,并且以产品的主键作为外键。

ie

Product Table
prod_num 
1
2
3


CD Table
prod_num                                  cd_title    cd_length
1(fk taken by Product table)            rock n roll       30


OtherProduct  
 prod_num                                  size           brand
 3 (fk taken by product table)             large          nikie

i want to extract information by sql query product numer, product type and description(if product is cd then title, cd_length and if product is belongs to other product then size, brand) 我想通过sql查询产品编号,产品类型和描述来提取信息(如果产品是cd,则标题,cd_length,如果产品属于其他产品,则大小,品牌)

I tried in this way, but it is not correct, confuse how to come to know product type and then hoe fetch detail of that product. 我以这种方式尝试过,但不正确,请混淆如何了解产品类型,然后再获取该产品的详细信息。

select product.prod_num from product, cd, otherProduct
where product.prod_num = cd.prod_num 

AND 

product.prod_num = other_product.product_num

i want to extract information by sql query product numer, product type and description(if product is cd then title, cd_length and if product is belongs to other product then size, brand) 我想通过sql查询产品编号,产品类型和描述来提取信息(如果产品是cd,则标题,cd_length,如果产品属于其他产品,则大小,品牌)

The question is about determination of the Subtype { CD | OtherProduct }, 问题是关于子类型{ CD | OtherProduct }, { CD | OtherProduct }, without the presence of a ProductType column in the Basetype. { CD | OtherProduct },而在基本类型中不存在ProductType列。 That is a valid assignment question. 这是一个有效的分配问题。

The answer requires an understanding of what a Subtype is. 答案需要了解什么是子类型。

  • There are two types of Subtype: Exclusive and Non-exclusive. 子类型有两种类型:排他性和非排他性。

  • This one is an Exclusive Subtype. 这是一个排他的子类型。 They require a Discriminator column in the Basetype, such as ProductType. 它们需要基本类型(例如ProductType)中的Discriminator列。

In this instance, the problem given does not have a Discriminator, you have to figure out the Subtypes without that. 在这种情况下,给出的问题没有鉴别符,您必须找出没有鉴别符的子类型。 There are integrity issues, but again, for a classroom problem, the absence of such is not "incorrect". 存在完整性问题,但是对于课堂问题,再次出现这种情况也不是“不正确的”。

Answer 回答

What is a database ? 什么是数据库?

  • The database is a collection of Facts. 该数据库是事实的集合。 Generally, each row is a Fact, collectively we say, each table is a collection of the instances of a Fact. 通常,每一行都是事实,我们总的来说,每个表都是事实实例的集合。

What is an Exclusive Subtype ? 什么是互斥子类型?

  • An Exclusive subtype is always a pair: the Basetype plus one Subtype, it is never either Basetpe xor Subtype alone. Exclusive子类型始终是一对:Basetype加一个Subtype,它永远不会单独是Basetpe xor或Subtype。

  • Thus while in the normal (not-a-subtype) case, a Fact is stored in one table, the Fact of a Subtype, its existence, is stored in two tables, the Basetype plus one Subtype. 因此,在正常(非子类型)情况下,事实存储在一个表中,子类型的事实及其存在被存储在两个表中,即基类型加一个子类型。

  • An existence check is simply a join (straight join, inner join, not outer, not left, not right). 存在检查仅是联接(直线联接,内部联接,不是外部联接,不是左联接,不是右联接)。

You can determine CD Facts as follows. 您可以按以下方式确定CD事实。 Once we determine them, we can assert the missing ProducteType: 一旦确定它们,就可以断言缺少的ProducteType:

    SELECT  CD.prod_num,
            prod_type = "C",
            cd_title,
            cd_length
        FROM Product P
            JOIN CD ON P.prod_num = CD.prod_num

To determine OtherProduct Facts: 要确定其他产品事实:

    SELECT  OP.prod_num,
            prod_type = "O",
            size,
            brand
        FROM Product P
            JOIN OtherProduct OP ON P.prod_num = OP.prod_num
  • No nulls. 无空值。

  • Scales beautifully. 鳞片精美。

If you need them in Views, stick CREATE VIEW AS in front of them 如果您在视图中需要它们,请将CREATE VIEW AS放在它们前面

If you need both Subtypes in a single View 1 : 如果在单个视图1中需要两个子类型:

    SELECT  CD.prod_num,
            prod_type = "C",
            cd_title,
            cd_length,
            size = "",
            brand = ""
        FROM Product P
            JOIN CD ON P.prod_num = CD.prod_num
    UNION
    SELECT  OP.prod_num,
            prod_type = "O",
            "",
            "",
            size,
            brand
        FROM Product P
            JOIN OtherProduct OP ON P.prod_num = OP.prod_num
  1. Note that a view is a derived relation, not a base relation (table), so we don't care that it has Nulls, whereas we would not implement Nulls in a base relation. 请注意,视图是派生关系,而不是基本关系(表),因此我们不在乎它是否具有Null,而不会在基本关系中实现Null。

  2. Nevertheless, NULL is a pretty stupid value to place in a report because it confuses the user, and then you have to spend time de-confusing them. 但是, NULL是放置在报表中的非常愚蠢的值,因为它会使用户感到困惑,然后您必须花费时间使它们混乱。 Thus it is good practice to substitute NULL with something that is not confusing. 因此,优良作法是将NULL替换为不会引起混淆的内容。

  3. I have given the column titles in the first SELECT, in order to have them displayed. 我在第一个SELECT,给出了列标题SELECT,以便显示它们。 Column titles in the second and subsequent SELECT are ignored. 第二个和后续SELECT中的列标题将被忽略。

Looks like you need a left join and sum IFNULL() trickery! 看来您需要左连接并加总IFNULL()

SELECT
  IF(cd.prod_num IS NULL,'other','cd') AS product_type,
  CONCAT (
    IFNULL(otherProduct.size, cd.cd_title),
    ', ',
    IFNULL(otherProduct.brand, CONCAT(cd.cd_length, ' mins'))
  ) AS description 
FROM
  product
  LEFT JOIN cd ON product.prod_num=cd.prod_num
  LEFT JOIN otherProduct ON product.prod_num=otherProduct.prod_num
;

You could create a view that unifies the type and the subtypes, more or less like the following 您可以创建一个统一类型和子类型的视图,大致如下所示

create view all_products as
select *
    from product
    inner join CD on (CD.prod_num=product.prod_num)
union all
select *
    from product
    inner join otherproduct (on otherproduct.prod_num = product.prod_num);

Then, you could query the view as follows: 然后,您可以按以下方式查询视图:

select * from all_product
 where prod_num in (1, 2, 3)

This has not been tested, so I may have a few typos, but I hope you get the idea. 这还没有经过测试,所以我可能会有一些错别字,但是希望您能理解。

This solution won't scale up well. 该解决方案无法很好地扩展。 With a few hundred products,it should run ok. 有几百种产品,它应该可以正常运行。 with a few million products, it will be too slow. 拥有数百万种产品,速度将会太慢。 It will also result in lots of NULLs in cases where a data item is inapplicable, because it pertains to the wrong subtype. 在数据项不适用的情况下,由于它属于错误的子类型,因此也会导致很多NULL。

You have not clearly explained what you want. 您尚未清楚说明您想要的内容。 Maybe it's this: 也许是这样的:

select prod_num,cd_title,cd_length,null as size,null as brand
from CD
union
select prod_num,null as cd_title,null as cd_length,size,brand
from OtherProduct

(If we want rows per condition1 AND rows per condition2 then we want rows per condition1 -OR- condition2 . These kinds of AND and OR mean a UNION of rows.) (如果我们想每个条件2每个条件1的行和列,然后我们希望每个条件1 -或- 条件2行。这些类型和和或平均行的UNION)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM