【问题标题】:SQL Query to output present guests in hotelSQL查询输出酒店当前客人
【发布时间】:2013-03-10 09:23:37
【问题描述】:

考虑上述关系。我正在尝试列出目前住在酒店的所有客人和家属,这意味着他们在房间里。

这是我的 SQL 查询:

SELECT g.FORENAME, g.SURNAME           
    FROM GUEST g
    INNER JOIN BOOKING b 
            ON g.GUESTID = b.GUESTID
    WHERE (b.DEPARTDATE > TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY') AND b.ARRIVEDATE < TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY'))
    UNION   
    SELECT d.FORENAME, d.SURNAME
    FROM DEPENDANT d
    INNER JOIN BOOKINGDEPENDANT bd 
            ON bd.DEPENDANTID = d.DEPENDANTID
    WHERE bd.BOOKINGID IN (SELECT b.BOOKINGID 
                            FROM BOOKING b
                            WHERE (b.DEPARTDATE > TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY') AND b.ARRIVEDATE < TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY')));

查询执行但显示没有选择行,当它应该这样做时。

这是我的 BOOKING 插入语句。

INSERT INTO BOOKING VALUES (2002, 5445, '19-MAR-2013', '10-JUN-2013', 250.00);

INSERT INTO BOOKING VALUES (2004, 3005, '19-MAR-2013', '21-MAR-2013', 250.00);

尽管客人 5445 和 3005 满足 where 条件及其相关预订,但未显示任何输出。我期待 5445 和 3005 的名称。

如果我删除以下行:

b.ARRIVEDATE < TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY')

将显示名称列表。但是这个逻辑是错误的,因为如果不考虑,您将无法检测到现在的客人。

我的问题是上面的行被错误地添加了?为什么在满足条件时不显示那些客人。他们毕竟是现在的客人。我能做些什么?

【问题讨论】:

    标签: sql oracle join union


    【解决方案1】:

    我认为问题在于您在比较字符串而不是日期。

    '19-MAR-2013' < '21-MAR-2013' => TRUE
    '10-JUN-2013' > '21-MAR-2013' => FALSE (as '10...' < '21...')
    

    将您的日期作为日期保存在数据库中。 如果您需要将它们作为文本进行比较,或者将它们转换为 YYYY-MM-DD 格式(这样字符串比较将匹配日期比较。

    注意:虽然正确的解决方案是更改列以将数据保存为日期,但下面是 SQL 的更正版本,它将与文本列一起使用(尽管远没有那么高效/正确):

    SELECT g.FORENAME, g.SURNAME           
    FROM GUEST g
    INNER JOIN BOOKING b 
        ON g.GUESTID = b.GUESTID
    WHERE CURRENT_DATE BETWEEN TO_DATE(b.ARRIVEDATE, 'DD-MON-YYYY') AND TO_DATE(b.DEPARTDATE, 'DD-MON-YYYY')
    
    UNION   
    
    SELECT d.FORENAME, d.SURNAME
    FROM DEPENDANT d
    INNER JOIN BOOKINGDEPENDANT bd 
        ON bd.DEPENDANTID = d.DEPENDANTID
    WHERE bd.BOOKINGID IN 
    (
        SELECT b.BOOKINGID 
        FROM BOOKING b
        WHERE CURRENT_DATE BETWEEN TO_DATE(b.ARRIVEDATE, 'DD-MON-YYYY') AND TO_DATE(b.DEPARTDATE, 'DD-MON-YYYY')
    );
    

    【讨论】:

    • ps。有关此主题的更多信息,另请参阅 stackoverflow.com/questions/10178292/…
    • @JohnBevan 嗨,约翰,我的列是 CREATE 表语句中定义的日期。在查询中我做了 to_char 已经看到其他讨论人们如何使用它们。但误解了这个概念。与 TO_CHAR 相反,我可以用什么替换它们?还是您的答案高于唯一的解决方案
    • 嘿@MuminAli;如果您的列已经是日期,只需将它们与 CURRENT_DATE 进行比较 - 已经返回日期,因此无需转换它。即WHERE CURRENT_DATE BETWEEN b.ARRIVEDATE AND b.DEPARTDATE
    • 没有选择的行就是它显示的内容。最初的问题。
    • 固定 :D 工作,它需要刷新更新的创建表。
    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    相关资源
    最近更新 更多