下面的两个查询中,哪个对 postgresql 来说最有效?并且在可读性等方面具有更好的风格。
区别在于语句的位置doctor.type != 'surgeon'
在 WHERE 子句中:
SELECT practice.name, doctor.name
FROM doctor
JOIN practice ON (doctor_code = code)
WHERE doctor.name LIKE '%son'
AND (doctor.type != 'surgeon');
Run Code Online (Sandbox Code Playgroud)
或者在 JOIN 子句中:
SELECT practice.name, doctor.name
FROM doctor
JOIN practice ON (doctor_code = code AND doctor.type != 'surgeon')
WHERE doctor.name LIKE '%son';
Run Code Online (Sandbox Code Playgroud) 我正在尝试通过 Postgres 中 jsonb 字段上的属性将普通表连接到具有 jsonb 字段的表。例子:
普通表:
create table Res
(
id uuid default uuid_generate_v4() not null
constraint res_pkey
primary key
)
;
Run Code Online (Sandbox Code Playgroud)
带有 jsonb 的表:
create table res_rem_sent
(
body jsonb not null,
search tsvector,
created_at timestamp with time zone default now(),
id uuid default uuid_generate_v4() not null
constraint res_rem_sent_pkey
primary key
);
create index idx_res_rem_sent
on res_rem_sent (body)
;
create index idx_search_res_rem_sent
on res_rem_sent (search)
;
Run Code Online (Sandbox Code Playgroud)
该body字段可能如下所示:{"resId": <GUID>, ....}
我想将res表连接到id等于给定 GUID id …
我有两个表,其中一个包含下载 url 的历史记录,而另一个表包含有关每个 url 的详细信息。
以下查询按过去一小时内的重复次数对 URL 进行分组。
SELECT COUNT(history.url) as total, history.url
FROM history
WHERE history.time > UNIX_TIMESTAMP()-3600
GROUP BY history.url
ORDER BY COUNT(history.url) DESC
LIMIT 30
Run Code Online (Sandbox Code Playgroud)
上面的查询大约需要 800ms 执行,不够快,但可以接受,
但是,当与缓存表连接时,新查询大约需要25s才能执行,速度非常慢。
SELECT th.total, th.url, tc.url, tc.json
FROM (SELECT COUNT(history.url) as total, history.url
FROM history
WHERE history.time > UNIX_TIMESTAMP()-3600
GROUP BY history.url
ORDER BY COUNT(history.url) DESC
LIMIT 30
) th
INNER JOIN (SELECT cache.url, cache.json FROM cache) tc
ON th.url = tc.url
GROUP BY th.url
ORDER BY th.total DESC
LIMIT …Run Code Online (Sandbox Code Playgroud) 我正在使用 MySQL。我有三张桌子,每张桌子都有一time列。
通过单个查询,我想计算between两个给定日期的行数。
我不需要表之间的连接(虽然它们是相关的),所以join没有必要。
是否可以?
失败的尝试 #1
SELECT
COUNT(a.time),
COUNT(b.time),
COUNT(c.time)
FROM
tbl1 AS a,
tbl2 AS b,
tbl3 AS c
WHERE
a.time BETWEEN '2018-03-07 18:32:55' AND '2018-03-07 20:46:55'
AND
b.time BETWEEN '2018-03-07 18:32:55' AND '2018-03-07 18:46:55'
AND
c.time BETWEEN '2018-03-07 18:32:55' AND '2018-03-07 18:46:55' ;
Run Code Online (Sandbox Code Playgroud) 我有一种感觉,答案是“这取决于……”,但我想知道是否有具体的答案。
在实体框架中,您使用 C# 代码构建查询,框架将转换为 SQL 并发送到服务器以下拉数据。假设我想从三个表中检索一条记录。我至少有三个选择:
使用直接 SQL(手动 ADO.NET),SELECT在同一命令中发送三个语句,并使用 DataReader 一次映射一个结果集。从数据库的角度来看,这显然是最好的方法,但它是最有效的方法,因为我无法使用实体框架方法。
从实体框架发送三个单独的命令 - 这需要到数据库服务器的三个往返:
Person person1 = context.Persons.First(p => p.PersonID == 1);
Car car1 = context.Cars.First(c => c.CarID == 1);
House house1 = context.Houses.First(h => h.HouseID == 1);
// translates to the following SQL, one roundtrip at a time:
SELECT TOP(1) [p].[PersonID], [p].[PersonName] FROM [Person] AS [p] WHERE [p].[PersonID] = 1
SELECT TOP(1) [c].[CarID], [c].[CarName] FROM [Car] AS [c] WHERE [c].[CarID] = 1
SELECT TOP(1) [h].[HouseID], [h].[HouseName] FROM …Run Code Online (Sandbox Code Playgroud) 我有一种感觉,这肯定被问过多次,但我只是找不到解决方案,甚至可能因为难以解释而提出问题。
我们都知道内连接基本上给出了两个表的“交集”。因此多个内连接给出了所有表的交集。但是,我希望获得一个内部连接,该连接获得表 B 与 A或表 C 与 A的交集。
对于获得所有组织的请求,我要么是主持人,要么是管理员。
SELECT *
FROM organization
INNER JOIN moderator_organization
ON organization.id = moderator_organization.organization AND moderator_organization.user = 10
INNER JOIN admin_organization
ON organization.id = admin_organization.organization AND admin_organization.user = 10
Run Code Online (Sandbox Code Playgroud)
然而,上面只会选择用户(ID 为 10)既是管理员又是组织者的组织,而不是其中任何一个都为真的组织。要在图表中可视化,我想:
红色区域是我想要请求的地方。
当我做这样的查询时,做笛卡尔积(交叉连接)背后的想法是什么 -
SELECT * FROM agents, orders
Run Code Online (Sandbox Code Playgroud)
我认为它们会连接(如pandas)。添加表格而不是乘以表格感觉更自然。
只是好奇,并没有在互联网上找到默认笛卡尔积背后的基本原理。我假设FROM table1, table2根据 SQL 的语法对于交叉连接可能更正确,但为什么呢?
我在这里似乎有类似的问题,但似乎没有一个答案符合我正在寻找的-
假设我有一张这样的桌子:
| 分配给 | 部门ID | 类型 |
|---|---|---|
| 玛丽 | 5001 | 初级 |
| 鲍勃 | 5002 | 中间 |
| 鲍勃 | 5003 | 初级 |
| 吉尔 | 5004 | 高的 |
| 鲍勃 | 5005 | 高的 |
| 鲍勃 | 5006 | 高的 |
另一个像这样:
| 用户 | 电话 | 地址 |
|---|---|---|
| 玛丽 | 111-222-3333 | 南巷111号 |
| 鲍勃 | 222-111-3333 | 北大道222号 |
| 吉尔 | 333-222-1111 | 555公路 |
我想在第一个表上输出带有左连接的第二个表,其中包含每个指定用户的“类型”总数(基本、中、高),因此它需要类似的内容:
| 用户 | 电话 | 小学总计 | 总中 | 总高 |
|---|---|---|---|---|
| 玛丽 | 111-222-3333 | 1 | 0 | 0 |
| 鲍勃 | 222-111-3333 | 1 | 1 | 2 |
| 吉尔 | 333-222-1111 | 0 | 0 | 1 |
我已经尝试过--Count(case when <table>.[type] = 'Elementary' then 1 else 0 end) AS ElementaryCount,,但这只是让我获得整个表,而不是左连接的用户。
有人知道我该怎么做吗?
在我的项目中,我有一张客户表,每个客户对每种产品都有自己的特价,这是一家小型企业,目前大约有 5 种产品。经理说以后可能会有更多的产品,但业务不会超过30个产品。对我来说,不创建特殊产品表而是向客户表添加列(每个新产品 - 新列)更容易。
人们建议我不要这样做,但我没有得到解释为什么仍然无法理解为什么在这种情况下产品的价格没有关系(每个客户都有自己的特价)在产品表中添加行比添加列更好产品到客户表?我能想到的唯一好处是只有 5 个产品的客户不必“携带”20 个可为空的产品(节省服务器空间)?
任何帮助将不胜感激
我有一个非常简单的查询:
SELECT COUNT(*)
FROM messages
INNER JOIN users ON messages.user_id = users.user_id
Run Code Online (Sandbox Code Playgroud)
加入需要 1146 毫秒,没有加入需要 220 毫秒(220 毫秒对我来说仍然很慢)。在包含 1,000,000+ 行的消息表上进行测试。
我在两个表 ( message_idand user_id)上都设置了主键,并设置了连接messages.user_idand的外键users.user_id。
此查询的原因是为分页系统提供记录总数。
我还能做些什么来加速查询?
join ×10
sql-server ×4
postgresql ×3
mysql ×2
performance ×2
sql-standard ×2
count ×1
foreign-key ×1
json ×1
t-sql ×1
union ×1