我们有一个表,用于存储问题的答案。我们需要能够找到对特定问题有特定答案的用户。因此,如果我们的表包含以下数据:
user_id question_id answer_value
Sally 1 Pooch
Sally 2 Peach
John 1 Pooch
John 2 Duke
Run Code Online (Sandbox Code Playgroud)
并且我们想要找到回答问题 1 的“Pooch”和回答问题 2 的“Peach”的用户,以下 SQL 将(显然)不起作用:
select user_id
from answers
where question_id=1
and answer_value = 'Pooch'
and question_id=2
and answer_value='Peach'
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是为我们正在寻找的每个答案自行加入表格:
select a.user_id
from answers a, answers b
where a.user_id = b.user_id
and a.question_id=1
and a.answer_value = 'Pooch'
and b.question_id=2
and b.answer_value='Peach'
Run Code Online (Sandbox Code Playgroud)
这是有效的,但由于我们允许任意数量的搜索过滤器,我们需要找到更有效的东西。我的下一个解决方案是这样的:
select user_id, count(question_id)
from answers
where (
(question_id=2 and answer_value = 'Peach')
or (question_id=1 and answer_value = 'Pooch')
)
group …Run Code Online (Sandbox Code Playgroud) 我有一个关于最佳方法的问题。当数据的大小可变时,我不确定哪种方法最好。
考虑以下 3 个表:
员工
EMPLOYEE_ID,EMP_NAME
项目
PROJECT_ID,PROJ_NAME
EMP_PROJ(以上两个表中的多对多)
EMPLOYEE_ID、PROJECT_ID
问题:给定一个 EmployeeID,找到与该员工关联的所有项目的所有员工。
我以两种方式尝试过这个。无论使用什么大小的数据,这两种方法都只有几毫秒的不同。
SELECT EMP_NAME FROM EMPLOYEE
WHERE EMPLOYEE_ID IN (
SELECT EMPLOYEE_ID FROM EMP_PROJ
WHERE PROJECT_ID IN (
SELECT PROJECT_ID FROM EMP_PROJ p, EMPLOYEE e
WHERE p.EMPLOYEE_ID = E.EMPLOYEE_ID
AND E.EMPLOYEE_ID = 123)
Run Code Online (Sandbox Code Playgroud)
走
select c.EMP_NAME FROM
(SELECT PROJECT_ID FROM EMP_PROJ
WHERE EMPLOYEE_ID = 123) a
JOIN
EMP_PROJ b
ON a.PROJECT_ID = b.PROJECT_ID
JOIN
EMPLOYEE c
ON b.EMPLOYEE_ID = c.EMPLOYEE_ID
Run Code Online (Sandbox Code Playgroud)
截至目前,我预计每个员工和项目大约有 5000 名……但不知道存在什么样的多对多关系。你会推荐哪种方法?谢谢!
编辑:方法 1 的执行计划
"Hash …Run Code Online (Sandbox Code Playgroud) 我正在尝试为员工时间记录完成一些报告。
我们有两个专门针对这个问题的表格。员工列在Members表中,他们每天输入他们已完成工作的时间条目并存储在Time_Entry表中。
使用 SQL Fiddle 的示例设置:http ://sqlfiddle.com/#!3/e3806/7
最终的结果我要的是一个表,表示所有的Members列中的列表,然后将展示他们的总和小时,在其他列查询的日期。
问题似乎是,如果Time_Entry表中没有特定成员的行,那么该成员现在有行。我尝试了几种不同的连接类型(左、右、内、外、全外等),但似乎都没有给我想要的,这将是(基于 SQL Fiddle 中的最后一个示例):
/*** Desired End Result ***/
Member_ID | COUNTTime_Entry | TIMEENTRYDATE | SUMHOURS_ACTUAL | SUMHOURS_BILL
ADavis | 0 | 11-10-2013 | 0 | 0
BTronton | 0 | 11-10-2013 | 0 | 0
CJones | 0 | 11-10-2013 | 0 | 0
DSmith | 0 | 11-10-2013 | 0 | 0
EGirsch | 1 | 11-10-2013 | 0.92 …Run Code Online (Sandbox Code Playgroud) 我正在处理复杂的问题,但我会将其简化为这个问题。
我有两张桌子
A [ID, column1, column2, column3]
B [ID, column1, column2, column3, column4]
Run Code Online (Sandbox Code Playgroud)
我想更新第三个:
C [ID, column1, column2,column3]
Run Code Online (Sandbox Code Playgroud)
我正在使用此查询更新另一个第三个表。
UPDATE C
set column1=t.firstTab, column2=t.secondTab, column3=t.thirdTab
from (select A.column1 as firstTab, B.column2 as secTab,
(A.column1 + B.column2) thirdTab
from A, B limit 1; ) as t ;
Run Code Online (Sandbox Code Playgroud)
我有:
UPDATE 0
Run Code Online (Sandbox Code Playgroud)
当我运行此查询时:
select A.column1 as firstTab, B.column2 as secTab, (A.column1 + B.column2) thirdTab
from A, B limit 1;
Run Code Online (Sandbox Code Playgroud)
我得到了结果。我错过了什么吗?
示例数据:http : //sqlfiddle.com/#!15/e4d08/5
如果所有连接都提供相同的结果,哪个连接性能更好?例如,我有两个表employees(emp_id,name, address, designation, age, sex)和work_log(emp_id,date,hours_wored). 获得一些特定的结果inner join并left join给出相同的结果。但是,我还有一些疑问,不仅限于这个问题。
架构:
CREATE TABLE "items" (
"id" SERIAL NOT NULL PRIMARY KEY,
"country" VARCHAR(2) NOT NULL,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"price" NUMERIC(11, 2) NOT NULL
);
CREATE TABLE "payments" (
"id" SERIAL NOT NULL PRIMARY KEY,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"amount" NUMERIC(11, 2) NOT NULL,
"item_id" INTEGER NULL
);
CREATE TABLE "extras" (
"id" SERIAL NOT NULL PRIMARY KEY,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"amount" NUMERIC(11, 2) NOT NULL,
"item_id" INTEGER NULL …Run Code Online (Sandbox Code Playgroud) Postgres 新手在这里。
我想知道这个查询是否经过优化?我试图仅加入 100% 必要的值,并将所有动态条件留在 WHERE 子句中。见下文。
SELECT *
FROM
myapp_employees
JOIN myapp_users ON
myapp_users.user_id=myapp_employees.user_id
JOIN myapp_contacts_assoc ON
myapp_contacts_assoc.user_id=myapp_users.user_id
JOIN myapp_contacts ON
myapp_contacts.contact_id=myapp_contacts_assoc.contact_id
WHERE
myapp_contacts.value='test@gmail.com' AND
myapp_contacts.type=(1)::INT2 AND
myapp_contacts.is_primary=(1)::INT2 AND
myapp_contacts.expired_at IS NULL AND
myapp_employees.status=(1)::INT2 AND
myapp_users.status=(1)::INT2
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
注意:对于上下文,此过程正在检查用户是否也是员工(提升的权限/不同的用户类型)。
无论如何,这是正确的方法吗?例如,JOIN ON 是否应该包含更多语句,例如检查 expired_at IS NULL?为什么或为什么这没有意义?
我已经通过使用解决了查询问题 ... row_number() over (partition by... 这是关于为什么我们不能在连接中使用具有空值的列的更一般的问题。为什么为了连接而 null 不能等于 null?
PostgreSQL 使用默认值,加上
default_statistics_target=1000
random_page_cost=1.5
Run Code Online (Sandbox Code Playgroud)
版本
PostgreSQL 10.4 on x86_64-pc-linux-musl, compiled by gcc (Alpine 6.4.0) 6.4.0, 64-bit
Run Code Online (Sandbox Code Playgroud)
我已经抽真空并分析过。查询非常简单:
SELECT r.price
FROM account_payer ap
JOIN account_contract ac ON ap.id = ac.account_payer_id
JOIN account_schedule "as" ON ac.id = "as".account_contract_id
JOIN schedule s ON "as".id = s.account_schedule_id
JOIN rate r ON s.id = r.schedule_id
WHERE ap.account_id = 8
Run Code Online (Sandbox Code Playgroud)
每id列都是主键,所有被连接的都是外键关系,每个外键都有一个索引。加上一个索引account_payer.account_id。
返回 76k 行需要 3.93s。
Merge Join (cost=8.06..83114.08 rows=3458267 width=6) (actual time=0.228..3920.472 rows=75548 loops=1)
Merge Cond: (s.account_schedule_id = "as".id)
-> Nested Loop …Run Code Online (Sandbox Code Playgroud) 哪个更快
SELECT * FROM X INNER JOIN Y ON x.Record_ID = y.ForignKey_NotIndexed_NotUnique
Run Code Online (Sandbox Code Playgroud)
或者
SELECT * FROM X INNER JOIN Y ON y.ForignKey_NotIndexed_NotUnique = x.Record_ID
Run Code Online (Sandbox Code Playgroud) join ×10
postgresql ×5
mysql ×2
optimization ×2
performance ×2
sql-server ×2
aggregate ×1
group-by ×1
null ×1
oracle ×1
reporting ×1
update ×1