我有一个查询来获取两个值:
string query = @"SELECT price, weight
FROM map
WHERE width = @width AND height = @height LIMIT 1";
if (_connSource.State != ConnectionState.Open)
_connSource.Open();
MySqlCommand cmd = new MySqlCommand(query, _connSource);
cmd.Parameters.AddWithValue("width", width);
cmd.Parameters.AddWithValue("height", height);
r = cmd.ExecuteReader();
if (!r.Read())
{
r.Close();
query = @"SELECT retail_price, 0
FROM globe
WHERE PK_Id = @PK_Id LIMIT 1"
cmd = new MySqlCommand(query, _connSource);
cmd.Parameters.AddWithValue("PK_Id ", 1);
r = cmd.ExecuteReader();
}
我需要根据条件获取price
和weight
,但如果表中没有,那么我需要另外两个字段retail_price
,从一个没有前一个表约束的全新表中得到一个常量0(无关紧要)。 我可以在一个查询中获取这两个吗?
注意:请给我优化的查询,这些查询不会强制多次读取相同的值(此功能在一次操作中执行数千次,因此速度非常关键 - 我之所以想要得到的原因它在一个查询中)。感谢..
答案 0 :(得分:3)
语法有点难看,但我认为你可以做到:
(SELECT price, weight
FROM map
WHERE width = @width AND height = @height LIMIT 1)
UNION ALL
(SELECT retail_price as price, 0 as weight
FROM globe
WHERE PK_Id = @PK_Id LIMIT 1)
返回0到2行。如果返回2行,则选择第1行。
编辑您可以尝试使用此怪异构造来避免第二次查询的成本。我不确定MySQL是否会很好地处理它,但它有可能避免第二个查询:
select
ifnull(price, (select retail_price from globe where PK_Id = @PK_Id LIMIT 1))
, ifnull(weight, 0)
from map
WHERE width = @width AND height = @height LIMIT 1
答案 1 :(得分:1)
如果没有Resrytrow到地图WHERE那么 DBNull将被全局值替换
SELECT
price = IFNULL(map.price,gl.price),
weight = IFNULL(map.weight,0)
FROM map
LEFT JOIN globe gl ON PK_Id = @PK_Id
WHERE width = @width AND height = @height
LIMIT 1
答案 2 :(得分:0)
由于您的“limit”子句保证每个查询最多有一行,您可以使用左连接,并使用“IF()”处理“map”记录的存在:
select ifnull(m.price,g.price), ifnull(m.weight,g.weight) from
(SELECT retail_price as price, 0 as weight
FROM globe
WHERE PK_Id = @PK_Id LIMIT 1) g
LEFT JOIN
(SELECT price, weight
FROM map
WHERE width = @width AND height = @height LIMIT 1) m
ON 1=1
上述查询假设地图表中的价格和权重不能为空。
答案 3 :(得分:0)
我偶然得到了一个非常hacky的解决方案。这是人们可以做到的:
SELECT price, weight
FROM map
WHERE width = @width AND height = @height LIMIT 1
UNION ALL
SELECT retail_price, 0
FROM globe
WHERE PK_Id = @PK_Id LIMIT 1
如果我在第一次选择中得到答案,LIMIT 1
子句实际上限制它读取第二个值。 请注意,我没有在任何地方添加括号,因此MySQL不会将其视为正常的UNION ALL 。阅读更多相关信息here和here
显然你可以这样做,以使其更有意义,但我认为它没有更好的表现:
SELECT price, weight
FROM map
WHERE width = @width AND height = @height LIMIT 1
UNION ALL
(SELECT retail_price, 0
FROM globe
WHERE PK_Id = @PK_Id LIMIT 1) LIMIT 1
这里因为我添加了括号,它的工作方式与普通的UNION ALL类似,即如果可能,我应该获取两个记录,但查询末尾的最后一个LIMIT 1
子句将结果限制为第一个集合。