如何处理这种类型的Oracle SQL问题

时间:2017-07-30 21:22:35

标签: sql oracle

只是有一个写SQL的问题 在ORACLE DB中,我在一个“APPLE”表中有不同的苹果行,其中“TAGS”包含此类苹果的所有功能。例如:

NAME, TAGS 
-----------
APPLE1, FUJI BOXED MEDIUM CALIFORNIA ...  
APPLE2, ORGANIC GALA PER_POUND LARGE FLORIDA ... 
APPLE3, RED_DELICIOUS MEDIA PACKED ORGANIC ... 
APPLE4, LARGE RED_DELICIOUS Mexico .... 
APPLE5, PACKED FUJI MEXICO LARGE 

现在我想要一个SQL查询来查找具有任何给定标记值的所有行,例如,“FUJI MEDIUM MEXICO”。这个SQL怎么样?

这与我正在进行的一个项目有关。在数据库中,为什么我有一个“TAG”列保留所有功能而不是单独的列,这是因为我们知道会引入越来越多的新标签值,所以我们不会添加越来越多的列喜欢将它们保存在一列中,这样代码不需要每次都更改。

谢谢,

杰克

5 个答案:

答案 0 :(得分:5)

你可以重新设计表格,看起来像这样:

name  | tag
----------
Apple1| FUJI
Apple1| BOXED
...
Apple5| PACKED
Apple5| FUJI

然后要查找包含标记fujimediummexico的所有项目,您可以执行以下操作:

SELECT name from tags where tag in ('FUJI','MEDIUM','MEXICO')
GROUP BY name

您可以找到标记为fujimediummexico的所有项目:

SELECT name from tags where tag in ('FUJI','MEDIUM','MEXICO')
GROUP BY name
HAVING count(tag) = 3

(假设(名称,标签)是唯一的)

这适用于任意数量的标签。还可以更轻松地从项目中删除标记,并允许您对标记进行连接和排序。

答案 1 :(得分:2)

我认为通过“FUJI MEDIUM MEXICO”你的意思是你要选择标有“FUJI”“MEDIUM”“MEXICO”的苹果,以任何顺序。在这种情况下,以下查询将起作用:

Select name From apple
Where tag like '%FUJI%' 
  And tag like '%MEDIUM%' 
  And tag like '%MEXICO%';

正如其他人所提到的,如果你想要一个不区分大小写的搜索,那么你需要添加适当的Upper或Lower函数,如下所示:

Select name From apple
Where Upper(tag) like '%FUJI%' 
  And Upper(tag) like '%MEDIUM%' 
  And Upper(tag) like '%MEXICO%';

为了提高效率,标签应存放在完全大写或完全小写的情况下。这样就不需要在每行的标记值上调用Upper()或Lower()函数,如果数据集非常大,可以节省大量的时间。

答案 2 :(得分:0)

除了糟糕的表格设计,这可以使用like评估来完成。

select
   apple
   tags
from
   table
where
   lower(tags) like '%tag_here%'

我在这里使用lower()功能可以更轻松地处理字符串套管。当您使用全部小写字符替换tag_here时。

话虽如此,你真的应该改进你的数据库设计。从存储和性能角度来看,这是非常低效的。更好的设计将有两个不同的表。一个人会存储苹果,第二个表会将带有外键的标签存储回苹果表。

enter image description here

答案 3 :(得分:0)

更好的设计将成为你的朋友。

三张桌子:

CREATE TABLE APPLE_TYPE
  (APPLE_TYPE    VARCHAR2(100));

CREATE TABLE APPLE_ATTRIBUTES
  (ATTRIBUTE_TYPE  VARCHAR2(100));

CREATE TABLE APPLES
  (APPLE_ID        NUMBER,
   APPLE_TYPE      VARCHAR2(100)
     CONSTRAINT APPLES_FK1
       REFERENCES APPLE_TYPE(APPLE_TYPE)
         ON DELETE CASCADE,
   ATTRIBUTE_TYPE  VARCHAR2(100)
     CONSTRAINT APPLES_FK2
       REFERENCES APPLE_ATTRIBUTES(ATTRIBUTE_TYPE)
         ON DELETE NO ACTION);

祝你好运。

答案 4 :(得分:0)

我会将这些标记创建为列,并为“其他”标记创建第二个表。

Table: Apples
Apple_ID  PK
Name
Where_Grown
Size

Table:  Apple_Tags
Tag_ID PK
Apple_ID FK 
Tag

Index:  Apple_Tags.Tag, Apple_ID

Data for Apple 1 is:
Apples Table
ID:  1
Name: Fuji
Where_Grown:  California
Size: Medium

Tags Table
Tag_ID: 1
Apple_ID: 1
Tag:  Boxed

查找标签:

select * from apples a inner join apple_tags t on a.apple_id = t.apple_id

注意我没有在一列中存储多个标签。这打破了列是原子的规范化的第一条规则。我将它们作为行存储在一个单独的表中。我也认识到苹果的名称,大小以及它所生长的地方都是所有苹果的共同属性。