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 子句中,或者必须是聚合(例如mincount),或者必须在功能上依赖于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 之间的结果不同的主要内容,如果未能解决你的问题,请参考以下文章

c# 判断sqllite 表是不是存在

翻译:select into outfile(已提交到MariaDB官方手册)

mariadb的select语句

MariaDB 存储过程 - 在 INSERT 语句中出现错误“缺少 SELECT”

mariadb数据库中select用法

mariadb数据库中select用法