我不得不求助于ORM不足的原始SQL(使用Django
1.7)。问题在于大多数查询最终都具有80-90%的相似性。在不违反可重用性的前提下,我无法找到一种可靠且可靠的方式来构建查询。
字符串连接是唯一的出路,即使用if- else
条件构建无参数查询字符串,然后使用准备好的语句安全地包含参数(以避免SQL注入)。我想采用一种简单的方法来为我的项目模板SQL,而不是重新发明一个小型ORM。
例如,考虑以下查询:
SELECT id, name, team, rank_score
FROM
( SELECT id, name, team
ROW_NUMBER() OVER (PARTITION BY team
ORDER BY count_score DESC) AS rank_score
FROM
(SELECT id, name, team
COUNT(score) AS count_score
FROM people
INNER JOIN scores on (scores.people_id = people.id)
GROUP BY id, name, team
) AS count_table
) AS rank_table
WHERE rank_score < 3
我怎样才能:
a)在上添加可选WHERE
约束,people
或
b)更改INNER JOIN
为LEFT OUTER
或
c)更改COUNT
为SUM
或
d)完全跳过该OVER / PARTITION
条款?
对于初学者,您可以修复语法,简化和澄清很多:
SELECT *
FROM (
SELECT p.person_id, p.name, p.team, sum(s.score)::int AS score
,rank() OVER (PARTITION BY p.team
ORDER BY sum(s.score) DESC)::int AS rnk
FROM person p
JOIN score s USING (person_id)
GROUP BY 1
) sub
WHERE rnk < 3;
建立在我更新的表格布局上。参见下面的小提琴。
您不需要其他子查询。窗口函数是 在 集合函数 之后 执行的,因此您可以像演示的那样嵌套它。
在谈论“等级”时,您可能想使用rank()
而不是row_number()
。
假设people.people_id
是PK,则可以简化GROUP BY
。
确保对所有可能不明确的列名进行表限定
然后,我将编写一个plpgsql函数,该函数接受可变部分的参数。实施a
-c
您的观点。d
尚不清楚,请留待您补充。
CREATE OR REPLACE FUNCTION f_demo(_agg text DEFAULT 'sum'
, _left_join bool DEFAULT FALSE
, _where_name text DEFAULT NULL)
RETURNS TABLE(person_id int, name text, team text, score int, rnk int) AS
$func$
DECLARE
_agg_op CONSTANT text[] := '{count, sum, avg}'; -- allowed functions
_sql text;
BEGIN
-- assert --
IF _agg ILIKE ANY (_agg_op) THEN
-- all good
ELSE
RAISE EXCEPTION '_agg must be one of %', _agg_op;
END IF;
-- query --
_sql := format('
SELECT *
FROM (
SELECT p.person_id, p.name, p.team, %1$s(s.score)::int AS score
,rank() OVER (PARTITION BY p.team
ORDER BY %1$s(s.score) DESC)::int AS rnk
FROM person p
%2$s score s USING (person_id)
%3$s
GROUP BY 1
) sub
WHERE rnk < 3
ORDER BY team, rnk'
, _agg
, CASE WHEN _left_join THEN 'LEFT JOIN' ELSE 'JOIN' END
, CASE WHEN _where_name <> '' THEN 'WHERE p.name LIKE $1' ELSE '' END
);
-- debug -- quote when tested ok
-- RAISE NOTICE '%', _sql;
-- execute -- unquote when tested ok
RETURN QUERY EXECUTE _sql
USING _where_name; -- $1
END
$func$ LANGUAGE plpgsql;
称呼:
SELECT * FROM f_demo();
SELECT * FROM f_demo('sum', TRUE, '%2');
SELECT * FROM f_demo('avg', FALSE);
SELECT * FROM f_demo(_where_name := '%1_'); -- named param
SQL小提琴
问题内容: 我正在尝试根据从表单接收的输入来构建搜索。 我想根据这些值建立一个查询,但是如果该字段没有值,我显然不想在搜索中包括它(搜索“”会改变结果) 我尝试了几种不同的方法,例如构建一个字符串以放置在其中: 但这似乎无法正常工作。我也尝试过像这样的“堆叠”搜索查询: 然后像这样执行搜索: 但这会导致500个错误(而且我不确定是否可以从中获取更多信息)。 请帮助新手动态建立猫鼬搜索查询:( 问题
Unix 至少设立了三层内部边界来防范恶意用户或有缺陷的程序。一层是内存管理:Unix 用硬件自身的内存管理单元(MMU)来保证各自的进程不会侵入到其它进程的内存地址空间。第二层是为多用户设置的真正权限组——普通用户(非 root用户)的进程未经允许,就不能更改或者读取其他用户的文件。第三层是把涉及关键安全性的功能限制在尽可能小的可信代码块上。在 Unix 中,即使是 shell(系统命令解释器)
问题内容: 我一直在尝试以编程方式重做我的应用程序上的工作。(不使用情节提要) 除了手动制作导航控制器外,我几乎完成了。 我一直在做一些研究,但找不到任何手动实现此方法的文档。(我开始将应用程序制作为单视图应用程序) 目前,我只有1个ViewController。当然是appDelegate 导航控制器将在应用程序的所有页面中使用。 如果有人可以帮助我,或发送指向一些适当文档的链接以编程方式进行此
问题内容: 我将C#与SMO一起使用,并尝试检测要连接到的SQL Server版本(例如,企业版,标准版)。我知道如何获取版本信息,但这只能告诉我SQL Server的版本(例如,SQL Server 2008与SQL Server 2005)。 有谁知道如何获得实际的产品版本(例如,企业版,标准版)? 我需要此信息,因为某些SQL Server功能只是企业级的。因此,我可以尝试调用它们并捕获异常
第7章讲解了Erlang的错误处理机制。这一章我们来看看怎样使用这些机制来构建健壮、容错的系统。 防范错误数据 回想一下在第??章(程序??.5)中描述的那个用来分析电话号码的服务程序。它的主循环包含了以下代码: server(AnalTable) -> receive {From, {analyse,Seq}} -> Result = lookup
问题内容: 有没有一种方法可以在Windows中创建链接? 我发现使用的样本或必须下载的样本。 我需要一个简单的解决方案。那可能吗? 问题答案: 好了,我不得不使用创建快捷方式的方法,但是实际上我需要的是一个文件夹,但是会创建一个。 最终我用来创建。