select *
from records
where id in ( select max(id) from records group by option_id )
Run Code Online (Sandbox Code Playgroud)
此查询即使在数百万行上也能正常工作.但是从解释声明的结果可以看出:
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=30218.84..31781.62 rows=620158 width=44) (actual time=1439.251..1443.458 rows=1057 loops=1)
-> HashAggregate (cost=30218.41..30220.41 rows=200 width=4) (actual time=1439.203..1439.503 rows=1057 loops=1)
-> HashAggregate (cost=30196.72..30206.36 rows=964 width=8) (actual time=1438.523..1438.807 rows=1057 loops=1)
-> Seq Scan on records records_1 (cost=0.00..23995.15 rows=1240315 width=8) (actual time=0.103..527.914 rows=1240315 loops=1)
-> Index Scan using records_pkey on records (cost=0.43..7.80 rows=1 width=44) (actual time=0.002..0.003 rows=1 loops=1057)
Index Cond: (id = (max(records_1.id)))
Total …Run Code Online (Sandbox Code Playgroud) sql postgresql query-optimization greatest-n-per-group groupwise-maximum
假设我有一个简化的模型,其中a patient可以有零或更多events.一个事件有a category和a date.我想支持以下问题:
Find all patients that were given a medication after an operation and
the operation happened after an admission.
Run Code Online (Sandbox Code Playgroud)
药物,手术和入院是所有类型的事件类别.有大约100种可能的类别.
我期待着1000名患者,每个患者每个类别有大约10个事件.
我想出的天真的解决方案是有两张桌子,一张桌子patient和一张event桌子.创建索引event.category,然后使用内部联接查询,如:
SELECT COUNT(DISTINCT(patient.id)) FROM patient
INNER JOIN event AS medication
ON medication.patient_id = patient.id
AND medication.category = 'medication'
INNER JOIN event AS operation
ON operation.patient_id = patient.id
AND operation.category = 'operation'
INNER JOIN event AS admission
ON admission.patient_id = patient.id
AND admission.category = 'admission'
WHERE …Run Code Online (Sandbox Code Playgroud) 我正在使用 PostgreSQL 9.4。
我有一张桌子workouts。results用户可以为每个创建多个workout,并且一个result有一个score.
给定一个锻炼 ID 列表和两个用户 ID,我想返回每个用户每次锻炼的最佳分数。如果用户没有该锻炼的结果,我想返回填充/空结果。
SELECT "results".*, "workouts".*
FROM "results" LEFT JOIN "workouts" ON "workouts"."id" = "results"."workout_id"
WHERE (
(user_id, workout_id, score) IN
(SELECT user_id, workout_id, MAX(score)
FROM results WHERE user_id IN (1, 2) AND workout_id IN (1, 2, 3)
GROUP BY user_id, workout_id)
)
Run Code Online (Sandbox Code Playgroud)
在此查询中,左连接充当内连接;如果用户没有得到锻炼结果,我不会得到任何填充。无论存在多少结果,此查询都应始终返回六行。
示例数据:
results
user_id | workout_id | score
-----------------------------
1 | 1 | 10
1 | 3 | 10
1 | 3 …Run Code Online (Sandbox Code Playgroud) 我在 PostgreSQL 中使用 Rails 4.2。我有一个Product模型和一个Purchase带有Product has many Purchases. 我想找到最近购买的独特产品。最初我尝试过:
Product.joins(:purchases)
.select("DISTINCT products.*, purchases.updated_at") #postgresql requires order column in select
.order("purchases.updated_at DESC")
Run Code Online (Sandbox Code Playgroud)
然而,这会导致重复,因为它试图找到对 ( product.idand purchases.updated_at) 具有唯一值的所有元组。但是我只想id在加入后选择不同的产品。如果产品 ID 在连接中多次出现,请仅选择第一个。所以我也试过:
Product.joins(:purchases)
.select("DISTINCT ON (product.id) purchases.updated_at, products.*")
.order("product.id, purchases.updated_at") #postgres requires that DISTINCT ON must match the leftmost order by clause
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为我需要product.id在order子句中指定,因为这个约束会输出意外的顺序。
实现这一目标的轨道方式是什么?
sql postgresql ruby-on-rails greatest-n-per-group ruby-on-rails-4.2
我有一个大表,我想按一个列值对其进行分组并生成另一个列值的聚合。作为一个聚合,我不关心实际值,只要它是出现在按列分组的任何行中的值。类似的东西coalesce(),例如产生它在输入集中接收的第一个非空值的聚合。
当然,coalesce()不是聚合函数,实际上没有聚合函数匹配我需要的行为,在文档中:
如何通过查询检索组中每个组的任何元素?我知道我可以使用min()ormax()但我宁愿避免将所有值相互比较来确定结果。一种可以防止为已经具有值的组点击更多页面的解决方案将是理想的。这是一个大表(磁盘上有几 GB),有大组(数十万行)。
我已经看到有递归 CTE 和横向连接。我正在尝试围绕这些进行思考,看看这些是否有帮助......
下面是一个例子:
with t1(x) as (select * from generate_series(0, 10, 1)),
t2(x, y) as (select * from t1, t1 t2)
select x
, any_element(y) -- how can I simulate this any_element() aggregate function?
from t2
group by x
order by x
Run Code Online (Sandbox Code Playgroud) 我正在开发一个简单的应用程序来返回随机选择exercises,每个选择一个bodypart.
bodypart是模型enum上的索引列Exercise.DB是PostgreSQL.
以下实现了我想要的结果,但感觉非常低效(每次击中db一次bodypart):
BODYPARTS = %w(legs core chest back shoulders).freeze
@exercises = BODYPARTS.map do |bp|
Exercise.public_send(bp).sample
end.shuffle
Run Code Online (Sandbox Code Playgroud)
因此,这给exercise每个随机bodypart,并在最后混合顺序.
我还可以将所有练习存储在内存中并从中选择; 但是,我想这会有可怕的扩展(目前只有十几个种子记录).
@exercises = Exercise.all
BODYPARTS.map do |bp|
@exercises.select { |e| e[:bodypart] == bp }.sample
end.shuffle
Run Code Online (Sandbox Code Playgroud)
对这些进行基准测试表明该select方法在小范围内更有效:
Queries: 0.072902 0.020728 0.093630 ( 0.088008)
Select: 0.000962 0.000225 0.001187 ( 0.001113)
MrYoshiji's answer: 0.000072 0.000008 0.000080 ( 0.000072)
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否有一种有效的方法来实现这一输出,如果是,那么这种方法可能是什么样子.理想情况下,我想将其保留为单个数据库查询.
很高兴使用ActiveRecord或直接在SQL中撰写.任何想法都非常感激.
核心需求:查找指定过滤条件, ,
的最新条目。可能有更多这样的过滤器,但无论如何,按提交日期返回最新的逻辑是相同的。有两个主要用途,一是在 UI 中分页查看,二是生成报告。person_idsubmission_datetypeplanstatus
WITH cte AS (
SELECT * FROM (
SELECT my_table.*, rank() OVER (PARTITION BY person_id ORDER BY submission_date DESC, last_updated DESC, id DESC) FROM my_table
) rank_filter
WHERE RANK=1 AND status in ('ACCEPTED','CORRECTED') AND type != 'CR' AND h_plan_id IN (10000, 20000)
)
SELECT
SELECT count(id) FROM cte group by id,
SELECT * FROM cte limit 10 offset 0;
Run Code Online (Sandbox Code Playgroud)
该方法group by也不适用于 CTE。计数查询中所有的联合null可能适用于组合,但不确定。
我想将这两个合并为1个查询的主要原因是因为表很大并且窗口函数很昂贵。目前我使用单独的查询,它们基本上都运行相同的查询两次。
Postgres 版本 12。 …
我正在从 UUID 获取用户数据WHERE empl_user_pub_uuid = 'e2bb39f1f28011eab66c63cb4d9c7a34'。
由于我不想进行额外的查询来获取额外的用户数据,所以我试图通过INSERT.
WITH _u AS (
SELECT
eu.empl_user_pvt_uuid,
ee.email,
ep.name_first
FROM employees.users eu
LEFT JOIN (
SELECT DISTINCT ON (ee.empl_user_pvt_uuid)
ee.empl_user_pvt_uuid,
ee.email
FROM employees.emails ee
ORDER BY ee.empl_user_pvt_uuid, ee.t DESC
) ee ON eu.empl_user_pvt_uuid = ee.empl_user_pvt_uuid
LEFT JOIN (
SELECT DISTINCT ON (ep.empl_user_pvt_uuid)
ep.empl_user_pvt_uuid,
ep.name_first
FROM employees.profiles ep
) ep ON eu.empl_user_pvt_uuid = ep.empl_user_pvt_uuid
WHERE empl_user_pub_uuid = 'e2bb39f1f28011eab66c63cb4d9c7a34'
)
INSERT INTO employees.password_resets (empl_pwd_reset_uuid, empl_user_pvt_uuid, t_valid, for_empl_user_pvt_uuid, token)
SELECT 'f70a0346-a077-11eb-bd1a-aaaaaaaaaaaa', '6efc2b7a-f27e-11ea-b66c-de1c405de048', '2021-04-18 …Run Code Online (Sandbox Code Playgroud) sql postgresql greatest-n-per-group sql-insert sql-returning
不确定这在 PostgreSQL 9.3+ 中是否可行,但我想在非唯一列上创建唯一索引。对于这样的表:
CREATE TABLE data (
id SERIAL
, day DATE
, val NUMERIC
);
CREATE INDEX data_day_val_idx ON data (day, val);
Run Code Online (Sandbox Code Playgroud)
我希望能够[快速]仅查询不同的日期。我知道我可以用来data_day_val_idx帮助执行不同的搜索,但如果不同值的数量大大少于索引覆盖中的行数,这似乎会增加额外的开销。就我而言,大约每 30 天就有 1 个是明显的。
创建关系表以仅跟踪唯一条目是我唯一的选择吗?思维:
CREATE TABLE days (
day DATE PRIMARY KEY
);
Run Code Online (Sandbox Code Playgroud)
并在每次插入数据时使用触发器更新它。
想象下一张桌子
售票处
========================
| id | question |
========================
| 1 | Can u help me :)? |
========================
Run Code Online (Sandbox Code Playgroud)
用户输入表
======================================================
| id | answer | dateCreated | ticket_id |
======================================================
| 2 | It's my plessure :)? | 2016-08-05 | 1 |
=======================================================
| 3 | How can i help u ? | 2016-08-06 | 1 |
======================================================
Run Code Online (Sandbox Code Playgroud)
那么我怎样才能为每个具有最小日期值的组获取行的 id
所以我预期的答案应该是这样的
====
| id |
====
| 2 |
====
Run Code Online (Sandbox Code Playgroud)
更新:
我在下一个查询中得到了解决方案
SELECT id FROM UserEntry WHERE datecreated IN …
postgresql ×10
sql ×9
activerecord ×1
exists ×1
group-by ×1
left-join ×1
performance ×1
ruby ×1
sql-insert ×1
unique-index ×1