SQL查询中如何将一个表的字段值作为另一个表的列名使用
问题原因
你写的SQL无法运行核心有两个问题:
- JOIN关联条件没有写在
ON子句后(写在WHERE里虽然部分数据库兼容,但不符合标准语法,也容易出现笛卡尔积问题) - SQL不支持动态列名引用:数据库解析SQL时会先识别所有引用的列,再读取数据行,你没法直接把某行数据里的字段值(比如
dep_apt_code里存储的ATL)直接作为列名去取另一张表的对应列,W.F.dep的写法会被数据库解析为「W schema下F表的dep字段」,和你的预期完全不符。
实现方法
方法1:CASE WHEN 条件匹配(兼容所有SQL数据库,适配你当前的表结构)
因为你当前Weather表的列是固定的机场编码,直接用CASE语句判断当前航班的出发机场编码,匹配对应列取值即可:
SELECT F.date, F.flight_num, F.dep_apt_code AS dep, F.arr_apt_code AS arr, CASE F.dep_apt_code WHEN 'ATL' THEN W.ATL WHEN 'IAD' THEN W.IAD WHEN 'JFK' THEN W.JFK WHEN 'SFO' THEN W.SFO END AS weather FROM Flights AS F INNER JOIN Weather AS W ON F.date = W.date;
运行后就能得到你预期的结果集。如果后续新增机场,只需要在CASE里补充对应的WHEN分支即可。
方法2:优化表结构(长期维护更推荐)
你现在的Weather表用了宽表设计,把每个机场作为单独列存储,扩展性很差——新增机场就要加字段,写查询的时候也要同步改逻辑。更合理的设计是把Weather表改成窄表,每行存储「日期+机场」维度的天气数据,结构参考:
| date | apt_code | weather |
|---|---|---|
| 2022-06-01 | ATL | cloudy |
| 2022-06-01 | IAD | windy |
| 2022-06-01 | JFK | rainy |
| 2022-06-01 | SFO | sunny |
| 2022-06-02 | ATL | sunny |
| 2022-06-02 | IAD | rainy |
| 2022-06-02 | JFK | rainy |
| 2022-06-02 | SFO | windy |
这种结构下查询不需要写任何条件分支,直接关联两个维度即可:
SELECT F.date, F.flight_num, F.dep_apt_code AS dep, F.arr_apt_code AS arr, W.weather FROM Flights AS F INNER JOIN Weather AS W ON F.date = W.date AND F.dep_apt_code = W.apt_code;
后续新增机场只需要往Weather表里插数据,不需要改表结构和查询逻辑。
内容的提问来源于stack exchange,提问作者wmentrekin
相关产品推荐
相关产品推荐

