我有这个名为profit_loss
的表:
+--------------------+------------+----------+-------------+------------------+
| timestamp | fee | fee_unit | profit_loss | profit_loss_unit |
+--------------------+------------+----------+-------------+------------------+
| lm83-1526098952020 | 0.00750007 | BNB | 0.09672160 | USDT |
| lm83-1526098952020 | 0.00750007 | BNB | 0.00000000 | BNB |
| lm83-1526098952020 | 0.00750007 | BNB | 0.00000050 | BTC |
+--------------------+------------+----------+-------------+------------------+
并且还有这个,名为trading_price
:
+--------------------+-----------+---------------+---------------+
| timestamp | pair_name | bid_price | ask_price |
+--------------------+-----------+---------------+---------------+
| lm83-1526098952020 | NEOUSDT | 63.14000000 | 63.20000000 |
| lm83-1526098952020 | NEOBTC | 0.00749700 | 0.00749900 |
| lm83-1526098952020 | NEOETH | 0.09287900 | 0.09319500 |
| lm83-1526098952020 | NEOBNB | 4.95100000 | 4.96700000 |
| lm83-1526098952020 | BNBUSDT | 12.73850000 | 12.74580000 |
| lm83-1526098952020 | BNBBTC | 0.00151130 | 0.00151190 |
| lm83-1526098952020 | BNBETH | 0.01873500 | 0.01876000 |
| lm83-1526098952020 | LTCBNB | 10.73000000 | 10.77000000 |
| lm83-1526098952020 | BCCBNB | 107.73000000 | 108.37000000 |
| lm83-1526098952020 | LTCUSDT | 136.80000000 | 137.14000000 |
| lm83-1526098952020 | LTCBTC | 0.01625800 | 0.01627000 |
| lm83-1526098952020 | LTCETH | 0.20172000 | 0.01627000 |
| lm83-1526098952020 | BCCUSDT | 1372.01000000 | 1374.11000000 |
| lm83-1526098952020 | BCCBTC | 0.16314900 | 0.16315100 |
| lm83-1526098952020 | BCCETH | 2.02004000 | 2.02785000 |
| lm83-1526098952020 | BTCUSDT | 8412.13000000 | 8412.14000000 |
| lm83-1526098952020 | ETHUSDT | 677.88000000 | 678.55000000 |
| lm83-1526098952020 | ETHBTC | 0.08055000 | 0.08060500 |
+--------------------+-----------+---------------+---------------+
如何LEFT JOIN
这些表,以便结果如下?
+--------------------+------------+----------+-------------+------------------+-----------+---------------+---------------+
| timestamp | fee | fee_unit | profit_loss | profit_loss_unit | pair_name | bid_price | ask_price |
+--------------------+------------+----------+-------------+------------------+-----------+---------------+---------------+
| lm83-1526098952020 | 0.00750007 | BNB | 0.09672160 | USDT | BNBUSDT | 12.73850000 | 12.74580000 |
| lm83-1526098952020 | 0.00750007 | BNB | 0.00000000 | BNB | BNBBNB | 1 | 1 |
| lm83-1526098952020 | 0.00750007 | BNB | 0.00000050 | BTC | BNBBTC | 0.00151130 | 0.00151190 |
+--------------------+------------+----------+-------------+------------------+-----------+---------------+---------------+
请注意,基于trading_price.pair_name
和profit_loss.fee_unit
合并,我只需要profit_loss.profit_loss_unit
。
但如果条件如下:
profit_loss.fee_unit
和profit_loss.profit_loss_unit
组合不存在,然后尝试相反的方式:
profit_loss.profit_loss_unit
和profit_loss.fee_unit
如何对LEFT JOIN
IF
这样的条件进行单一查询?
答案 0 :(得分:1)
我们可以使用两个左连接操作,尝试获取两个匹配的行,然后使用SELECT列表中的表达式来测试是否找到了匹配的行。
SELECT p.timestamp
, ...
, CASE WHEN t.timestamp IS NOT NULL
THEN t.pairname
ELSE r.pairname
END AS pairname
, CASE WHEN t.timestamp IS NOT NULL
THEN t.bidprice
ELSE r.bidprice
END AS bidprice
, IF(t.timestamp IS NULL, r.askprice, t.askprice) AS askprice
FROM profit_loss p
LEFT
JOIN trading_price t
ON t.timestamp = p.timestamp
AND t.pairname = CONCAT(p.fee_unit,p.profit_loss_unit)
LEFT
JOIN trading_price r
ON t.timestamp IS NULL
AND r.timestamp = p.timestamp
AND r.pairname = CONCAT(p.profit_loss_unit,p.fee_unit)
WHERE ...
ORDER BY ...
在LEFT JOIN到r中,t.timestamp
上的条件将检查我们是否找到了来自t
的匹配行。如果我们找到匹配的行,则此条件将评估为FALSE,因此r
中的任何行都不会匹配。相反,如果t
没有匹配的行,则此条件将评估为TRUE,因此我们将从r
返回任何匹配的行。
如果t
中有多个匹配的行,则此查询将从p
返回该行的多个副本,这是t
中每个匹配行的副本。 (如果t
中没有匹配的行,那么与r
相同的问题。)(我们之所以提到这一点,是因为不能保证不会有超过一个匹配的行。 )
这只是一种方法的例子;还有其他查询模式可以获得相同的结果。
修改强>
注意:
当p
或t
中没有匹配的行时,查询将从r
返回一行。如果要求只有在找到匹配的行时才返回p
的行,那么我们可以在ORDER BY之前的HAVING子句中处理该条件,该条件测试是否返回了行< / p>
HAVING (t.pairname IS NOT NULL OR r.pairname IS NOT NULL)
如果我们有保证 askprice
和bidprice
不是NULL,那么我们可以简化SELECT列表中的表达式
, IFNULL(t.pairname,r.pairname) AS pairname
, IFNULL(t.bidprice,r.bidprice) AS bidprice
, IFNULL(t.askprice,r.askprice) AS askprice
我们可以在SELECT列表中使用各种表达式来获得相同的结果。