我想表明有多少校友参加了社交活动

时间:2016-07-31 08:01:55

标签: sql oracle

我想要一个输出来显示有多少校友参加了此次活动 我有事件表

CREATE TABLE EVENT 
(EVENTID INTEGER CONSTRAINT EVENT_ID_PK PRIMARY KEY,
EDATEANDTIME VARCHAR2(20),
EVENUE VARCHAR2(30),
EAUDIENCE VARCHAR2(30),
EATTENDED VARCHAR2(30),
EVENT_ALUMNI INTEGER,
CONSTRAINT EVENT_ALUMNI_FK FOREIGN KEY (EVENT_ALUMNI) REFERENCES
ALUMNI(ALUMNIID));

这是我在Event

中插入的内容
INSERT INTO EVENT VALUES(25993, 'Jan 14, 2015', 'Concorde Hall', 'Tobias, Tucker, Felix, Nicole, Desiree, Taylor, Frant, Ifeoma, Forrest, Stewart, Cole, Arthur, Thomas, Bo, Lucian', 
'Tobias, Tucker, Felix, Nicole, Desiree, Taylor, Frant, Ifeoma, Forrest, Stewart, Cole, Arthur, Thomas, Bo',17337);


INSERT INTO EVENT VALUES(23823, 'July 18 2015', 'Rochester Hotel', 'Joan, Thalia, Haleeda', 'Joan, Haleeda'
    ,19927);

我有一个查看声明,以查看有多少人参加

CREATE VIEW VIEWH AS SELECT ETYPE, EDATEANDTIME, COUNT (*) EATTENDED FROM EVENT 
WHERE EDATEANDTIME LIKE '%2015%' AND ETYPE = 'Social'
GROUP BY ETYPE, EDATEANDTIME, EATTENDED;

这是我遇到问题的地方。当我运行查询时,输出是我只有一个人参加了这个事件而不是10或15

image

我想知道我哪里出错了。

3 个答案:

答案 0 :(得分:0)

您的设置存在一些潜在问题,我在您的问题评论中提到了一对。

具体关于计数:你的第一个问题是你在GROUP BY子句中有EATTENDED。为什么?这几乎肯定意味着每组只有一行。

然后你的下一个问题是用逗号分隔的字符串计算标记。正如TheGameiswar所示,一种方法是使用regexp_count()。 (错误......他/她的解决方案已经消失了?无论如何,我说的是......)

另一种方法是使用length()translate()

select ...   , 1 + length(EATTENDED) - length(translate(EATTENDED, ',', '') as ATT_CNT  ...

关于此的几点说明:

长度差异,就像regexp_count()一样,会计算字符串中的逗号。你可以添加一个来计算令牌(你不关心有多少逗号,你关心用逗号分隔多少个名字)。 translate()regexp_count()工作得更快(所有regexp函数都非常强大,但速度较慢,因此只有在真正需要它们时才应该使用它们,如果性能很重要); length不会增加很多开销,因为在Oracle中,VARCHAR2的长度总是被计算并存储为字符串内部表示的一部分。

我为结果列提供了不同的别名;在原始查询中,您对基表中的列使用相同的名称EATTENDED,并在视图中使用此数字列的别名。你可以做到,这是合法的,但几乎肯定会在将来引起问题。

答案 1 :(得分:0)

这是因为COUNT给出结果中的“行”数而不是“列中的值”的数量。

给你一个简单的例子

example1_table:

 col1
 --------
 a
 b
 c

SELECT COUNT(col1) FROM example1_table; // The result is 3, as there are three rows  

example2_table:

 col1  
 --------
 a,b,c

SELECT COUNT(col1) FROM example1_table; // The result is 1, as there is only one row (it is not about number of values in it)

注意:

如@mathguy所述,您可以使用更好的数据库结构 不要只使用一个表EVENT创建两个表,而是table1 table2,这样您就可以避免冗余。

CREATE TABLE table1 
(EVENTID INTEGER CONSTRAINT EVENT_ID_PK PRIMARY KEY,
EDATEANDTIME VARCHAR2(20),
EVENUE VARCHAR2(30),
EVENT_ALUMNI INTEGER,
CONSTRAINT tab1_FK FOREIGN KEY (EVENT_ALUMNI) REFERENCES
ALUMNI(ALUMNIID));

CREATE TABLE table2
(
EAUDIENCE VARCHAR2(30),
EATTENDED VARCHAR2(30),
tab2ID INTEGER
CONSTRAINT tab2_FK FOREIGN KEY (tab2ID) REFERENCES
tab1(EVENT_ALUMNI));

答案 2 :(得分:0)

如果您不想在表格中进行任何更改,假设两个与会者名称之间始终存在逗号,您可以尝试:

CREATE VIEW VIEWH AS SELECT ETYPE, EDATEANDTIME, regexp_count(EATTENDED,',')+1 FROM EVENT WHERE EDATEANDTIME LIKE '%2015%' AND ETYPE = 'Social' GROUP BY ETYPE, EDATEANDTIME;