我有这个查询
SELECT *, COUNT(app.id) AS totalApps FROM users JOIN app ON app.id = users.id
GROUP BY app.id ORDER BY app.time DESC LIMIT ?
应该从相关表中另一列(时间)排序的“用户”获得所有结果(应用程序表中的ID引用用户表中的ID)。
我的问题是,分组是在按日期排序之前完成的,所以得到的结果非常旧。但是我需要进行分组才能获得不同的用户,因为每个用户可以有多个“应用程序” ...是否有其他方法可以实现这一目标?
表用户:
id TEXT PRIMARY KEY
表格应用程序:
id TEXT
time DATETIME
FOREIGN KEY(id) REFERENCES users(id)
在我的SELECT查询中,我想获取一个由app.time列排序的用户列表。但是因为一个用户可以关联多个应用程序记录,所以我可以得到重复的用户,这就是为什么我使用GROUP BY的原因。但是后来订单搞砸了
答案 0 :(得分:1)
由于您需要每个组中的最新日期,因此您可以$router->get('/end', ['as'=>'name_here', function()]);
:
MAX
答案 1 :(得分:1)
您可以使用窗口COUNT
:
SELECT *, COUNT(app.id) OVER(PARTITION BY app.id) AS totalApps
FROM users
JOIN app
ON app.id = users.id
ORDER BY app.time DESC
LIMIT ?
答案 2 :(得分:1)
潜在的问题是SELECT是一个聚合查询,因为它包含GROUP BY子句:-
简单的SELECT语句有两种类型-聚合和 非汇总查询。一个简单的SELECT语句是一个聚合查询 如果包含GROUP BY子句或一个或多个聚合 功能在结果集中。
SQL As Understood By SQLite - SELECT
因此该组列的值将是该组列的任意值(我怀疑首先是根据扫描/搜索,因此是较低的值):-
如果SELECT语句是不带GROUP BY的聚合查询 子句,然后对结果集中的每个聚合表达式求值 一次遍及整个数据集。中的每个非聚合表达式 结果集对任意选择的行评估一次 数据集。每个行都使用相同的任意选择的行 非聚合表达式。或者,如果数据集包含零行,则 每个非集合表达式都针对包含 完全是NULL值。
因此,简而言之,当它是聚合查询时,您不能依赖不属于组/聚合的列值。
因此必须使用聚合表达式(例如max(app.time))检索所需的值。但是,您不能按此值进行排序(不确定确切的原因,因为它可能在效率方面是固有的)
您可以做的是使用查询建立CTE,然后在不涉及聚合的情况下进行排序。
请考虑以下内容,我认为这类似于您的问题:-
DROP TABLE IF EXISTS users;
DROP TABLE If EXISTS app;
CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT);
INSERT INTO users (username) VALUES ('a'),('b'),('c'),('d');
CREATE TABLE app (the_id INTEGER PRIMARY KEY, id INTEGER, appname TEXT, time TEXT);
INSERT INTO app (id,appname,time) VALUES
(4,'app9',721),(4,'app10',7654),(4,'app11',11),
(3,'app1',1000),(3,'app2',7),
(2,'app3',10),(2,'app4',101),(2,'app5',1),
(1,'app6',15),(1,'app7',7),(1,'app8',212),
(4,'app9',721),(4,'app10',7654),(4,'app11',11),
(3,'app1',1000),(3,'app2',7),
(2,'app3',10),(2,'app4',101),(2,'app5',1),
(1,'app6',15),(1,'app7',7),(1,'app8',212)
;
SELECT * FROM users;
SELECT * FROM app;
SELECT username
,count(app.id)
, max(app.time) AS latest_time
, min(app.time) AS earliest_time
FROM users JOIN app ON users.id = app.id
GROUP BY users.id
ORDER BY max(app.time)
;
结果为:-
尽管每个组的最新时间都已提取,但最终结果却没有按照您的想象进行排序。
将其包装到CTE中可以解决例如:-
WITH cte1 AS
(
SELECT username
,count(app.id)
, max(app.time) AS latest_time
, min(app.time) AS earliest_time
FROM users JOIN app ON users.id = app.id
GROUP BY users.id
)
SELECT * FROM cte1 ORDER BY cast(latest_time AS INTEGER) DESC;
现在:-
答案 3 :(得分:0)
答案 4 :(得分:0)
尝试按ID和时间分组,然后按时间排序。
select ...
group by app.id desc, app.time
我认为id在应用表中是唯一的。 以及您如何分配ID?也许您有足够的通过id desc
进行订购