Python SQLite:根据转换组的结果并用名称填充ID
我的问题相当具体,如果你有更好的标题,请建议一个。另外,格式也不好——不知道如何组合列表和代码块 我有一个SQLite3数据库,其中包含以下内容(架构的相关部分):Python SQLite:根据转换组的结果并用名称填充ID,python,sqlite,pivot,Python,Sqlite,Pivot,我的问题相当具体,如果你有更好的标题,请建议一个。另外,格式也不好——不知道如何组合列表和代码块 我有一个SQLite3数据库,其中包含以下内容(架构的相关部分): 购买大约有450万条记录,用户大约有30万条,销售大约有10万条,而地点大约有250条-只是为了测量数据量 我所希望的用途是生成一个JSON对象,并将其传递给另一个应用程序,通过执行以下操作将其压缩成大量内容: -通过location_id,user_id-IOW将购买和销售分组到一个公共表中,获得每个位置每个用户的“操作”数。我能
购买
大约有450万条记录,用户
大约有30万条,销售
大约有10万条,而地点
大约有250条-只是为了测量数据量
我所希望的用途是生成一个JSON对象,并将其传递给另一个应用程序,通过执行以下操作将其压缩成大量内容:
-通过location_id,user_id-IOW将购买和销售分组到一个公共表中,获得每个位置每个用户的“操作”数。我能做到的,结果是
loc | usid | loccount
-----------------------
1 | 1246 | 123
1 | 2345 | 1
13 | 1246 | 46
13 | 8732 | 4
27 | 2345 | 41
(至少它看起来不错,总是很难说有这么多书;查询:
select location_id,user_id,count(location_id) from
(select location_id,user_id from purchases
union all
select location_id,user_id from sales)
group by location_id,user_id order by user_id`
)
-然后,把那张巨大的桌子调换一下,这样我就能:
usid | loc1 | loc13 | loc27
---------------------------
1246 | 123 | 46 | 0
2345 | 1 | 0 | 41
8732 | 0 | 4 | 0
这是我做不到的,这是我在这个问题上绝对关键的一点。我尝试了一些在网上找到的东西,特别是在这里,但我刚刚开始使用SQLite,不理解很多查询
-最后,将表转换为纯文本,以便将其写入JSON:
user | AAAA | BBBBB | CCCCC
---------------------------
zeta | 123 | 46 | 0
beta | 1 | 0 | 41
iota | 0 | 4 | 0
我可能需要做大量的实验和内部连接,尽管我总是不确定处理此类数据量的最佳方法是什么,因此我不介意使用指针
如果有必要的话,整个过程都是用Python的sqlite3接口编写的。最后,我想做一些事情,我可以对每个用户执行一个“for”循环,以生成JSON,这当然非常简单。查询是否需要很长时间并不重要(考虑使用子查询来实现所需的转置输出:
SELECT DISTINCT m.usid,
IFNULL((SELECT t1.loccount FROM tablename t1
WHERE t1.usid = m.usid AND t1.loc=1),0) AS Loc1,
IFNULL((SELECT t2.loccount FROM tablename t2
WHERE t2.usid = m.usid AND t2.loc=13),0) AS Loc13,
IFNULL((SELECT t3.loccount FROM tablename t3
WHERE t3.usid = m.usid AND t3.loc=27),0) AS Loc27
FROM tablename As m
或者,您可以使用嵌套的IF
语句(或者在使用case/WHEN
的SQLite中)作为派生表:
SELECT temp.usid, Max(temp.loc1) As Loc1,
Max(temp.loc13) As Loc13, Max(temp.loc27) As Loc27
FROM
(SELECT tablename.usid,
CASE WHEN loc=1 THEN loccount ELSE 0 As Loc1 END,
CASE WHEN loc=13 THEN loccount ELSE 0 As Loc13 END,
CASE WHEN loc=27 THEN loccount ELSE 0 As Loc27 END
FROM tablename) AS temp
GROUP BY temp.usid
老实说,在分组步骤的背景下尝试实现这一点让我很头疼。您似乎假设存在一个表-将第一步的结果插入一个临时表会更好吗?现在,我尝试使用包含上述查询的视图来实现这一点,除了不起作用之外,速度非常慢。(我只是在你使用m的地方替换了我的观点。)编辑:哦,顺便说一句,如果我没有误解你的查询,你在m.usid之后漏掉了一个逗号。好吧,我用临时表中第一次查询的结果在整个数据库中尝试了这个方法,它可以工作,但速度慢得不可行-每个用户大约需要5秒,这会让几十万人觉得不实用。太糟糕了。谢谢你不过,你的回答!因为我不太熟悉SO的礼仪:只有当回答是一个实际的解决方案时,才会对其进行投票,对吗?不是作为“谢谢”或者在其他情况下是否有用。但是你提到:“询问是否需要很长时间并不重要(尽管如此,我还是添加了另一个解决方案。另外,请重新运行子查询,因为我在子查询的
loc
表引用中做了一个小小的疏忽,它需要一个DISTINCT
(因为usids重复了)。令人惊讶的是,第二个查询速度非常快-即使没有静态临时表,也只需几秒钟!非常感谢!(还有“很长时间!”“对于我来说,计算时间最多是一个小时,而在CPU完全使用的情况下,您的第一个查询将花费超过19天的时间。)
SELECT temp.usid, Max(temp.loc1) As Loc1,
Max(temp.loc13) As Loc13, Max(temp.loc27) As Loc27
FROM
(SELECT tablename.usid,
CASE WHEN loc=1 THEN loccount ELSE 0 As Loc1 END,
CASE WHEN loc=13 THEN loccount ELSE 0 As Loc13 END,
CASE WHEN loc=27 THEN loccount ELSE 0 As Loc27 END
FROM tablename) AS temp
GROUP BY temp.usid