SQL - 仅当表A为空时才从表B中选择

时间:2014-05-22 15:34:04

标签: sql sql-server select

我有一个包含列的主表FXTB;货币,汇率,日期(仅限今天的日期)。

我想生成一个!从表FXTB中选择SQL但是如果我提供一个较旧的日期(它将从FXTB返回任何内容,它将从另一个名为FXTBHistory的表中选择) 具有相同的列名但包含不同日期的数据。

如果不够清楚,请告诉我。

3 个答案:

答案 0 :(得分:4)

做一个UNION

SELECT currency, rate, date FROM FXTB WHERE date = @date
UNION
SELECT currency, rate, date FROM FXTBHistory WHERE date = @date

如果第一个结果为空 - 第二个结果将提供结果。如果由于某种原因,两个结果之间存在重复的条目 - UNION将消除重复项

如果您收到不完全重复(不同的费率,根据您的评论在同一日期),但您只想记录 - 您可以尝试这样的事情(未经测试)

WITH FXTBAll AS
    (SELECT currency, rate, date, ROW_NUMBER() OVER (PARTITION BY currency, date ORDER BY currency, date) RN FROM 
        (SELECT currency, rate, date FROM FXTB WHERE date = @date
        UNION
        SELECT currency, rate, date FROM FXTBHistory WHERE date = @date) T
    )
SELECT currency, rate, date FROM FXTBAll WHERE RN = 1

它仍然使用相同的UNION,但在它上面构建一个CTE并使用ROW_NUMBER()进行分区为每个组选择第一条记录

答案 1 :(得分:1)

为了补充使用union的方法,在这个星座中,LEFT OUTER JOIN也是可能的。 ifnull将返回FXTB值,仅当它们为null时,才会返回FXTBHistory值:

SELECT ifnull(FXTB.currency, FXTBHistory.currency) as currency,
       ifnull(FXTB.rate, FXTBHistory.rate) as rate, 
       ifnull(FXTB.date, FXTBHistory.date) as date
FROM FXTBHistory LEFT OUTER JOIN FXTB
  ON FXTBHistory.currency = FXTB.currency
  AND FXTBHistory.date = FXTB.date
  WHERE ifnull(FXTB.date, FXTBHistory.date) = @date
UNION
SELECT ifnull(FXTB.currency, FXTBHistory.currency) as currency,
       ifnull(FXTB.rate, FXTBHistory.rate) as rate, 
       ifnull(FXTB.date, FXTBHistory.date) as date
FROM FXTBHistory RIGHT OUTER JOIN FXTB
  ON FXTBHistory.currency = FXTB.currency
  AND FXTBHistory.date = FXTB.date
  WHERE ifnull(FXTB.date, FXTBHistory.date) = @date;

请参阅http://sqlfiddle.com/#!2/c97e23/6以了解相关信息。

答案 2 :(得分:1)

如果您想要FXTBHistory中的记录,只有在@date的任何货币的FXTB 中不存在记录

SELECT currency, rate, date
FROM FXTB
WHERE date = @date
UNION ALL
SELECT currency, rate, date
FROM FXTBHistory
WHERE date = @date
  AND NOT EXISTS (SELECT 1 FROM FXTB WHERE date = @date)

如果您想逐个货币地选择FXTB和FXTBHistory:

SELECT
 @date                                AS date,
 COALESCE(new.currency, old.currency) AS currency,
 COALESCE(new.rate    , old.rate)     AS rate
FROM FXTB new
FULL JOIN FXTBHistory old ON (
  new.currency = old.currency AND
  new.date     = old.date
)
WHERE new.date = @date
  OR  old.date = @date