|
我希望能够unnest有很多JOINs的复杂SQL查询中使用PostgreSQL中函数。这是查询示例:, L2 S6 K( z# X% l, M2 s+ c+ u$ T
SELECT 9 as keyword_id,COUNT(DISTINCT mentions.id) as total,tags.parent_id as tag_idFROM mentionsINNER JOIN taggings ON taggings.mention_id = mentions.idINNER JOIN tags ON tags.id = taggings.tag_idWHERE mentions.taglist && ARRAY[9] AND mentions.search_id = 3GROUP BY tags.parent_id我想在taggings因为我的mentions有一个表叫 taglist* 的 整数数组
' r5 }3 a" X! }1 O) U+ x, P- ^所有链接的字段,字段tag id组成。*mentions" C3 y; u( }& [# X" B
我尝试了以下操作:3 f" F1 I4 l, q. N) N
SELECT 9 as keyword_id,COUNT(DISTINCT mentions.id) as total,tags.parent_id as tag_id FROM mentions INNER JOIN tags ON tags.id IN (SELECT unnest(taglist))WHERE mentions.taglist && ARRAY[9] AND mentions.search_id = 3 GROUP BY tags.parent_id该方法有效,但结果不同于第一个查询。! S) m4 H4 t5 _1 }' O& \& V
所以我要做的是SELECT unnest(taglist)在JOIN查询中使用的结果用于补偿taggings表。
# G+ {5 ]( ?1 _0 z: ?1 d$ a我怎样才能做到这一点?
: d9 @" Q9 \+ Z9 V! c! g8 CUPDATE: taglist以及提到的标记ID列表相同。6 z: z" f0 L6 s T
6 U. `, J' M) n9 \5 F 解决方案: 0 H8 q4 V' G* J. c0 k
从技术上讲,您的查询可能是这样工作的(查询目标无法完全确定):( [: _: v; U1 F$ U* s b' d% [
SELECT 9 AS keyword_id,count(DISTINCT m.id) AS total,t.parent_id AS tag_idFROM ( SELECT unnest(m.taglist) AS tag_id FROM mentions m WHERE m.search_id = 3 AND 9 = ANY (m.taglist) ) m JOIN tags t USING (tag_id) -- assumes tag.tag_id!GROUP BY t.parent_id;但在我看来,你在这里走错了方向。通常,冗余阵列将被删除。taglist并保留标准化的数据库架构。然后,您的原始查询应该能够很好地服务,只使用别名缩短语法:
( I+ @7 `1 `! ^/ T7 ESELECT 9 AS keyword_id,count(DISTINCT m.id) AS total,t.parent_id AS tag_idFROM mentions mJOIN taggings mt ON mt.mention_id = m.idJOIN tags t ON t.id = mt.tag_idWHERE 9 = ANY (m.taglist)AND m.search_id = 3GROUP BY t.parent_id;解开谜团 你不同结果的根本原因是不幸的命名协议,这是一些 具有挑战性的知识ORM 强加给人。 F% I4 S- Y5 B" s3 ~
我说的** ~~id~~** 是列名。不要在有多个表的数据库中使用这种反模式。是的,这基本上意味着 任何1 c4 M- j8 P0 X Y, L" Z3 j6 U
数据库。一旦添加了一堆表(这就是你在数据库中 所做 ),你最终会得到一堆名字id。毫无意义。
& t& Q* N" B- c, Q名为表的ID列tag应为 tag_id (除非有另一个描述性名称)。永远不要。id。3 {( k* Y$ Z6 A9 ^$ p. r
您的查询无意中计数,tags而不是mentions:
# p; a* q* |1 z* h" E: T! @6 V: [SELECT 25 AS keyword_id,count(m.id) AS total,t.parent_id AS tag_idFROM ( SELECT unnest(m.taglist) AS id FROM mentions m WHERE m.search_id = 4 AND 25 = ANY (m.taglist) ) mJOIN tags t USING (id)GROUP BY t.parent_id;它应该这样工作:0 z& d7 e: Z; V, p% }( C9 ?* p
SELECT 25 AS keyword_id,count( **DISTINCT** m.id) AS total,t.parent_idFROM ( SELECT **m.id** ,unnest(m.taglist) **AS tag_id** FROM mentions m WHERE m.search_id = 4 AND 25 = ANY (m.taglist) ) mJOIN tags t **ON t.id = m.tag_id**GROUP BY t.parent_id;我还DISTINCT向您添加count()在查询过程中迷路。 |
|