【问题标题】:How can I write this SQL query?如何编写此 SQL 查询?
【发布时间】:2015-08-14 17:21:22
【问题描述】:

我想知道是否可以就这个 sql 查询获得一些帮助。这是来自我失败但现在想学习的测试。我花了很多时间,看了关于sql的教程,但我仍然不明白它是怎么写的。..

有 2 个包含航班信息的表(flights、occupation_flights),任务是: 编写一个查询,提供接下来 7 天的航班列表,并显示航班、可用座位数、占用数座位和占用座位的百分比。

FLIGHTS:                    
FLIGHT  ID_COMPANY   DATE      ORIGIN   DESTINATION PLACES
1003       D3      20/01/2006   MADRID  LONDRES       40
1007       AF      20/01/2006   PARIS   MALAGA        12
1003       15      30/01/2006   MADRID  LONDRES       20
1007       AF      30/01/2006   PARIS   MALAGA        17

(PLACES 显示每个航班提供的位置数量)

OCCUPATION_FLIGHTS:
FLIGHT ID_COMPANY   DATE    PASSENGER   SEAT
1003    IB       20/01/2006 07345128H   01V
1003    IB       20/01/2006 1013456213  01P
1003    IB       20/01/2006 08124356C   02V
1003    IB       20/01/2006 57176355K   02P
1007    AF       20/01/2006 27365138A   
1003    IB       30/01/2006 734512811   01V
1003    IB       30/01/2006 1013456213  02V
1003    IB       30/01/2006 57176355K   

(当 SEAT 为空时,表示尚未出票)。 TEST DATA 我想获得一些可用座位,我应该总结每个航班和日期的乘客不是空的情况,然后从 PLACES 中提取。 所以我开始了:

SELECT 
f.flight, 
f.places - (SELECT (CASE WHEN of.passanger IS NOT NULL THEN 1 ELSE 0 END)      
FROM occupation_flights AS of GROUP BY of.flight, of.date) AS available,
f.places - (SELECT (CASE WHEN of.passanger IS NULL THEN 1 ELSE 0 END) FROM occupation_flights AS of GROUP BY of.flight, of.date) AS occupied,
100.0 * ((f.places - (SELECT (CASE WHEN of.passanger IS NOT NULL THEN 1 ELSE 0 END) FROM occupation_flights AS of GROUP BY of.flight, of.date)) / f.places AS %occupied
FROM flights AS f
JOIN occupation_flights AS of ON f.flight=of.flight
WHERE f.date BETWEEN DateAdd(DD,-7,GETDATE() ) and GETDATE() 
GROUP BY f.flight

但是还没完,因为我真的不明白怎么让他同时按航班和日期分组计算,因为有相同航班号但不同日期的航班。我也无权访问表,测试是在纸上,并表明您知道如何编写 sql 查询。 非常感谢您的任何见解! 非常感谢!

【问题讨论】:

  • 我将您的数据分组在一个 sqlfiddle 中:sqlfiddle.com/#!9/d62a4 随时使用 TEST DATA 之类的内容编辑您的帖子,然后链接其上的 url,以便其他人也拥有这些数据,我会尝试得到你需要的东西,但我不是最擅长这些事情的:p
  • 你确定你用的是mysql吗? getdate 和 dateadd 不是 mysql 函数
  • 您好 Jeremy,非常感谢您的回答。我现在将查看所有 cmets 并尝试理解其逻辑。非常感谢这个 sql fiddle,我不知道这样的东西存在,它让事情变得更容易!我不知道我实际上是否使用mysql,我以前在工作中总是使用pgadmin postgre或smth,而这个任务只是来自我失败的sql知识测试......
  • 老实说,我也只知道他们大约一个月,所以没有羞耻,直到我加入这个网站,我才知道有这样的东西存在跨度>

标签: mysql sql


【解决方案1】:

Mysql 符合: SQLFIDDLE

SELECT f.flight,f.mydate,f.places - count(of.seat) as available_seats,
        count(of.seat) as occupied,
        count(of.seat)/f.places * 100 as percentage_occupied
FROM flights f
JOIN occupation_flights of
ON f.flight = of.flight AND f.mydate = of.mydate
WHERE of.mydate BETWEEN DATE_ADD(CURDATE(), INTERVAL -7 DAY)AND CURDATE() 
group by f.flight, f.mydate

【讨论】:

    【解决方案2】:
    select t1.flight,
       t1.date,
       t1.places,
       t3.c,
       t1.places-IFNULL(t3.c, 0) as empty
    from flights t1 
    left join(
        select count(t2.seat) as c, t2.flight, t2.date
            from occupation_flights t2
        where seat is not null
            group by flight, date
            ) t3 
        on t1.flight= t3.flight and t1.date= t3.date
    

    这是结果

    PS。在我的代码中,使用了 MySql 函数 IFNULL(),应该将其替换为另一个数据库实现中的其他类似函数。

    【讨论】:

    • ...类似COALESCE(),同样适用于MySQL,符合ansi标准。
    【解决方案3】:
    SELECT
        f.flight, f.mydate, f.id_company, origin, destination,
        places, (places - COALESCE(t.ocupped_seats, 0)) as available_places,
        IFNULL(t.ocupped_seats, 0) as ocupped_places,
        CONCAT(ROUND(COALESCE(places/COALESCE(t.ocupped_seats, 0), 0), 2), '%') as percentage
    FROM
        flights as f
    LEFT JOIN
        (SELECT
             flight, mydate,id_company, COUNT(seat) as ocupped_seats
         FROM
             occupation_flights
         WHERE
             seat IS NOT NULL
         GROUP BY
             flight, mydate) as t
         ON
             f.flight = t.flight AND f.mydate LIKE t.mydate
    WHERE
        f.mydate BETWEEN CURDATE() AND CURDATE()+7
    

    DEMO(感谢Jeremy C. 构建架构和Strawberry 用于COALLESCE 函数)

    结果:

    【讨论】:

      猜你喜欢
      • 2013-02-01
      • 2012-02-29
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      相关资源
      最近更新 更多