SqLite和MariaDb SELECT之间的结果不一样

时间:2018-02-20 08:49:53

标签: mysql sqlite mariadb sqlite-net groupwise-maximum

我在Debian服务器上有2个表,游乐设施和步骤。

从Xamarin应用程序中,我从此服务器(RefitNewtonsoft JsonSQLite-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 个答案:

答案 0 :(得分: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,而是指定从{{1}完全过滤掉一条记录的条件{1}}:

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 :当然,您必须决定该条件应该是什么。