用于在一行中列出行的SQL查询

时间:2017-05-24 11:39:47

标签: sql ms-access

下面显示名为“PRIZE”的表的值

PRIZE

event_code  place  prizemoney
0101        1      $120
0101        2      $60
0101        3      $30
0102        1      $10
0102        2      $5
0103        1      $100
0103        2      $60
0103        3      $40
0201        1      $10
0201        2      $5
0401        1      $1000
0401        2      $500
0401        3      $250
0501        1      $10
0501        2      $5

现在的问题是:

对于每个至少有三个奖项的活动,请在一行中列出可获得一等奖,二等奖和三等奖的event_id和奖金。按event_id排序表。尽管您的属性名称可能不同,但结果将显示如下:

event_Id   first    second   third
101        120       60       30

这就是我接触解决方案的方式

SELECT A.event_id, B.place, C.place, D.place
FROM PRIZE AS A, PRIZE AS B, PRIZE AS C, PRIZE AS D
WHERE A.event_id = B.event_id
AND A.event_id = C.event_id
AND A.event_id = D.event_id;

我尝试使用SELF(递归)JOIN但它仍然显示错误。

这个问题的SQL查询怎么样?

1 个答案:

答案 0 :(得分:0)

你可以试试这个

SELECT p.event_id,  
       (SELECT prizemoney  
        FROM prize first  
        WHERE first.place = 1  
        AND   first.event_id = p.event_id) AS "first",  
       (SELECT prizemoney  
        FROM prize second  
        WHERE second.place = 2  
        AND   second.event_id = p.event_id) AS "second",  
       (SELECT prizemoney  
        FROM prize third  
        WHERE third.place = 3  
        AND   third.event_id = p.event_id) AS "third",  
FROM (SELECT DISTINCT event_id FROM prize) p  
ORDER BY p.event_id;  

使用索引的数据约束

如果您还没有(event_id, place),可以考虑使用UNIQUE索引。{p>这将阻止具有相同(event_id, place)组合但具有不同prizemoney的多行,这将回答问题“第5项活动的第一名获胜者的奖金是多少?我不知道,可能是10或100,因为有两行......“。

查询效果

如果您希望DBMS不读取子选择中每个prizemoney的数据库页面,那么您可以在(event_id, place, prizemoney)上拥有另一个UNIQUE索引,这样DBMS就可以读取该奖金使用“INDEX ONLY SCAN”。您将需要两个索引 - 第一个限制您的需求,第二个是prizemoney查找具有索引访问而没有表访问。三列上的第二个索引将复制表中的所有数据,可能浪费空间。首先尝试没有此索引。如果性能需要它,请添加所有列索引。