0

我在 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,但这并没有改变任何东西。

4

1 回答 1

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

于 2018-02-20T09:27:50.187 回答