SqlLite 和 MariaDb SELECT 之间的结果不同
Posted
技术标签:
【中文标题】SqlLite 和 MariaDb SELECT 之间的结果不同【英文标题】:Not the same result between SqLite and MariaDb SELECT 【发布时间】:2018-07-30 13:38:31 【问题描述】:我在 Debian 服务器上有 2 张桌子、游乐设施和台阶。
从 Xamarin 应用程序中,我从该服务器(Refit、Newtonsoft Json 和 SQLite-net PCL 包)获取数据以填充本地表。
当我在 mariadb 上使用这个查询时:
SELECT 1_steps.*
FROM 1_rides, 1_steps
WHERE 1_rides.id=1_steps.ride_id
AND 1_rides.start=1
GROUP BY 1_rides.id
我得到了正确的结果(每次骑行的第一步,然后从 1 开始)
但是当使用 Sqlite 的等价物时:
SELECT Steps.*
FROM Rides,Steps
WHERE Rides.Id=Steps.RideId
AND Rides.Start=1
GROUP BY Rides.Id
结果,我得到了每次(相同)骑行的最后步骤!
无论是 mariadb 还是 sqlite,每个表都有一个主键(id
字段)。
我检查了一下,数据的发送、接收和保存顺序相同。
只需在移动应用中添加:
foreach (var step in await App.RestClient.getSteps())
if (dbCon.InsertOrReplace(step) != 1)
....
我尝试添加ORDER BY Rides.Id
,但这并没有改变任何东西。
【问题讨论】:
【参考方案1】:您依赖的东西是严格的 SQL 标准所不允许的:只要有 group by
子句,select
子句中的字段也必须出现在 group by
子句中,或者必须是聚合(例如min
、count
),或者必须在功能上依赖于group by
字段。
在您的情况下,这些条件不满足,因此如果数据库引擎允许这样做,它将必须决定在同一组中选择哪个值:第一个、最后一个或其他值。
处理这个问题的方法是通过指定一个聚合来明确你想要在这种情况下得到什么:
SELECT 1_steps.id,
min(1_steps.step),
max(1_steps.whatever),
avg(1_steps.some_number),
FROM 1_rides
INNER JOIN 1_steps
ON 1_rides.id=1_steps.ride_id
WHERE 1_rides.start=1
GROUP BY 1_rides.id
您没有指定表的字段,但思路应该很清楚:分别列出字段(不是*
),并将聚合类型应用于您需要的它们。
另类
如果您对汇总任何内容不感兴趣,但只希望每次骑行时从 steps
中获取一条特定记录,则不要使用 group by
,而是指定从 steps
中准确过滤该一条记录的条件:
SELECT 1_steps.*
FROM 1_rides
INNER JOIN 1_steps
ON 1_rides.id=1_steps.ride_id
WHERE 1_rides.start=1
AND 1_steps.step = 1
ORDER BY 1_rides.id
注意条件1_steps.step = 1
:当然,您必须决定该条件应该是什么。
【讨论】:
非常感谢您的解释 :) 快速而完整。我选择了第一个完美运行的解决方案 :)以上是关于SqlLite 和 MariaDb SELECT 之间的结果不同的主要内容,如果未能解决你的问题,请参考以下文章
翻译:select into outfile(已提交到MariaDB官方手册)