查询要么输出太多数据,要么只在一列中输出

时间:2017-10-05 13:16:24

标签: sql oracle

我试图在5月6日和5月13日为所有会话输出SESSIONID,BUILDINGWING,SPEAKERNAME,ROOMCAPACITY,SESSIONSDATE。我试过这两个问题:

SELECT DISTINCT SESSIONID, BUILDINGWING, SPEAKERNAME, ROOMCAPACITY, SESSIONDATE
FROM CONFERENCESESSION, BUILDING, ROOM, SPEAKER
WHERE ROOM.BUILDINGNO = CONFERENCESESSION.BUILDINGNO
AND ROOM.ROOMNO = CONFERENCESESSION.ROOMNO
AND CONFERENCESESSION.SPEAKERID = SPEAKER.SPEAKERID
AND SESSIONDATE LIKE '06/JUN/%'
OR SESSIONDATE LIKE '13/MAY/%'
ORDER BY SESSIONID ASC;

这个输出~700行,这是不正确的

SELECT TO_CHAR(SESSIONDATE)
FROM CONFERENCESESSION
WHERE SESSIONDATE LIKE '06/JUN/%'
OR SESSIONDATE LIKE '13/MAY/%'
UNION
SELECT TO_CHAR(ROOMCAPACITY)
FROM ROOM
UNION
SELECT TO_CHAR(BUILDINGWING)
FROM BUILDING
UNION
SELECT TO_CHAR(SPEAKERNAME)
FROM SPEAKER
UNION
SELECT TO_CHAR(ROOMCAPACITY)
FROM ROOM;

我认为这个会话会返回正确数量的会话,但它全部在一列中

2 个答案:

答案 0 :(得分:0)

使用EXTRACT获取日期的数字组成部分:

AND ( EXTRACT( DAY FROM SESSIONDATE ) =  6 AND EXTRACT( MONTH FROM SESSIONDATE ) = 6 )
OR  ( EXTRACT( DAY FROM SESSIONDATE ) = 13 AND EXTRACT( MONTH FROM SESSIONDATE ) = 5 )

此外,BUILDING表没有连接条件,因此使用的是CROSS JOIN。如果您使用新的ANSI连接语法,则可以更清楚地看到:

SELECT DISTINCT
       SESSIONID,
       BUILDINGWING,
       SPEAKERNAME,
       ROOMCAPACITY,
       SESSIONDATE
FROM   CONFERENCESESSION
       INNER JOIN ROOM
       ON (    ROOM.BUILDINGNO = CONFERENCESESSION.BUILDINGNO
           AND ROOM.ROOMNO     = CONFERENCESESSION.ROOMNO )
       INNER JOIN BUILDING
       ON ( ) -- You have no condition that goes here
       INNER JOIN SPEAKER
       ON ( CONFERENCESESSION.SPEAKERID = SPEAKER.SPEAKERID )
WHERE  ( EXTRACT( DAY FROM SESSIONDATE ) =  6 AND EXTRACT( MONTH FROM SESSIONDATE ) = 6 )
OR     ( EXTRACT( DAY FROM SESSIONDATE ) = 13 AND EXTRACT( MONTH FROM SESSIONDATE ) = 5 )
ORDER BY SESSIONID ASC;

答案 1 :(得分:0)

您没有加入BUILDING表。这会将记录数乘以建筑物数量,因为执行了CROSS JOIN!加入它或放弃它!

SELECT C.SESSIONID, B.BUILDINGWING, S.SPEAKERNAME, R.ROOMCAPACITY, C.SESSIONDATE
FROM
    CONFERENCESESSION C
    LEFT JOIN ROOM R
        ON C.BUILDINGNO = R.BUILDINGNO AND
           C.ROOMNO = R.ROOMNO
    LEFT JOIN BUILDING B
        ON C.BUILDINGNO = B.BUILDINGNO
    LEFT JOIN SPEAKER S
        ON C.SPEAKERID = S.SPEAKERID
WHERE
    C.SESSIONDATE LIKE '06/JUN/%' OR C.SESSIONDATE LIKE '13/MAY/%'
ORDER BY
    C.SESSIONID ASC;

同样使用modern JOIN-syntax。区分连​​接和实际条件更容易,忘记连接的错误不再发生。

如果查询正确并且数据一致,则不需要DISTICT子句。

使用别名。它使查询更紧凑和可读。

您似乎在文本列中包含日期,或者至少您使用字符串语义处理日期。日期应该在DATE列中,并使用日期函数或作用于日期类型的比较运算符进行处理!没有必要进行字符串操作来分析日期。