【发布时间】:2014-08-24 21:49:31
【问题描述】:
我有一个 SQLite 数据库 (v. 3.8.1),其架构有些不寻常,无法更改。
出于这个问题的目的,有 5 个表(t1 到 t5),我需要使用来自 t1 和 t5 的数据创建一个汇总报告,但是我需要在 t5 中引用的数据只能基于收集与 t1 到 t4 中的记录的关系。
为了帮助澄清 - 假设 t1 保存有关文档的数据。该文档随后可以再进行 1 到 4 次迭代(每次迭代中都有不同的字段可用,因此有 5 个不同的表,而不仅仅是 1 个表中的一个标志来表示它所处的迭代)。
我对初始记录/文档(保存在 t1 中)是否已达到其最终迭代感兴趣(在 t5 中存在一个 ParentGUID,当跟进表链时,最终到达 t1 或不) .
t1 有一个 GUID(文本)字段,t2 到 t5 有 GUID 和 ParentGUID 字段(也是文本)。不必填充 t2 到 t5 中的 ParentGUID 字段(在某些情况下可以跳过文档迭代),但是当 ParentGUID 有一个值时,它将始终是来自前一个表的 GUID(例如,如果 t5 有一个 ParentGuid值,它将是来自 t1、t2、t3 或 t4 的 GUID)。
这意味着我想要来自 t1 的所有不同记录,然后对于每个来自 t5 的值(或多个值)(如果存在),否则为 null。
如果 t5 记录中的 ParentGuid 字段值是 t4 中记录的 GUID,并且该 t4 记录中的 ParentGuid 字段值是 t1 中记录的 GUID,则认为该特定 t1 记录已达到其最终迭代。
同样,ParentGUID > 将被视为 t1 > t5、初始 > 最终迭代的 GUID 链接包括:
t1 > t2 > t3 > t4 > t5
t1 > t2 > t3 > t5
t1 > t2 > t4 > t5
t1 > t2 > t5
t1 > t3 > t4 > t5
t1 > t3 > t5
t1 > t4 > t5
t1 > t5
或以图形表示:
考虑以下测试模式:
CREATE TABLE Table1
("GUID" TEXT, "Name" TEXT)
;
CREATE TABLE Table2
("GUID" TEXT, "ParentGUID" TEXT)
;
CREATE TABLE Table3
("GUID" TEXT, "ParentGUID" TEXT)
;
CREATE TABLE Table4
("GUID" TEXT, "ParentGUID" TEXT)
;
CREATE TABLE Table5
("GUID" TEXT, "Name" TEXT, "Amount" REAL, "ParentGUID" TEXT)
;
INSERT INTO Table1
("GUID", "Name")
VALUES
('ABC', 'A1')
;
INSERT INTO Table1
("GUID", "Name")
VALUES
('DEF', 'A2')
;
INSERT INTO Table1
("GUID", "Name")
VALUES
('GHI', 'A3')
;
INSERT INTO Table2
("GUID", "ParentGUID")
VALUES
('JKL', 'GHI')
;
INSERT INTO Table2
("GUID", "ParentGUID")
VALUES
('MNO', '')
;
INSERT INTO Table2
("GUID", "ParentGUID")
VALUES
('PQR', 'GHI')
;
INSERT INTO Table3
("GUID", "ParentGUID")
VALUES
('STU', 'MNO')
;
INSERT INTO Table3
("GUID", "ParentGUID")
VALUES
('STU', 'GHI')
;
INSERT INTO Table3
("GUID", "ParentGUID")
VALUES
('VWX', 'PQR')
;
INSERT INTO Table4
("GUID", "ParentGUID")
VALUES
('YZA', 'VWX')
;
INSERT INTO Table4
("GUID", "ParentGUID")
VALUES
('BCD', '')
;
INSERT INTO Table4
("GUID", "ParentGUID")
VALUES
('EFG', 'GHI')
;
INSERT INTO Table5
("GUID", "ParentGUID", "Amount", "Name" )
VALUES
('HIJ', 'EFG', -500, 'E3')
;
INSERT INTO Table5
("GUID", "ParentGUID", "Amount", "Name" )
VALUES
('KLM', 'YZA', -702, 'E2')
;
INSERT INTO Table5
("GUID", "ParentGUID", "Amount", "Name" )
VALUES
('NOP', '', 220, 'E8')
;
INSERT INTO Table5
("GUID", "ParentGUID", "Amount", "Name" )
VALUES
('QRS', 'GHI', 601, 'E4')
;
我想做的是获取 t1 中的所有记录,然后显示来自 t5 的所有相关 Amount 字段的总和(以上面列出的任何方式相关),以及来自所有相关 Name 字段的 group_concat t5.
使用上面的示例架构,它看起来像:
t1.Name total(t5.Amount) group_concat(t5.Name)
--------------------------------------------------
A1 0.00
A2 0.00
A3 -601.00 E2,E3,E4
我尝试了一堆不同的连接,但没有任何效果......要么我的 Total/Group_Concat 单元格中的项目太多(由于多次添加项目而总数太高,并且多个重复名称,例如“ E4,E4,E4,E4,E2,E3,E3,E4,E4..."),或者我只能从 t5 (601.00, E4) 中获取一个直接链接到 t1 的项目。
例如,查询只给了我 t1 记录 GHI 的 E4/601.00 结果:
SELECT DISTINCT t1.guid "OriginalGuid", t1.name "OriginalName", TOTAL(t5."Amount") as "TotalAmount", group_concat(t5.Name) AS "FinalNames"
FROM
Table1 t1
LEFT JOIN Table5 t5 ON (t1.GUID=t5.ParentGUID)
LEFT JOIN Table4 t4 ON (t1.GUID=t4.ParentGuid AND t5.ParentGuid=t4.Guid)
LEFT JOIN Table3 t3 ON (t1.GUID=t3.ParentGuid AND (t4.ParentGuid=t3.Guid OR t5.ParentGuid=t3.Guid))
LEFT JOIN Table2 t2 ON (t1.GUID=t2.ParentGuid AND (t3.ParentGuid=t2.Guid AND ((t4.ParentGuid=t3.Guid And t5.ParentGuid=t4.guid) or (t5.ParentGuid=t3.Guid)) OR (t4.ParentGuid=t2.Guid and t5.ParentGuid=t4.Guid) OR (t5.ParentGuid=t2.Guid)))
GROUP BY t1.GUID;
遗憾的是,我周末的大部分时间都在研究这个问题,但我一直没能找到可行且性能合理的东西(我有一些东西似乎适用于小型数据集,但对我的完整数据集花费了 分钟,这太长了 - 虽然不幸的是,我已经丢失了 SQL)。
我现在正在继续研究解决方案,如果我找到它,我会在此处发布答案,但如果有任何帮助/想法,我将不胜感激!
这是我的 SQL Fiddle:http://sqlfiddle.com/#!5/1a2ac/55
提前感谢您的帮助。
【问题讨论】:
-
对于表 5 中的 E3 条目,您的 SQL 小提琴数据为 -500,而不是上面示例中的 -50。
标签: sql sqlite join aggregate-functions multiple-tables