这可能是一个愚蠢的问题,我怀疑我不能这样做,但是 SQL 中是否有一个结构可以让我执行以下操作:
SELECT whatever WHERE col1,col2 IN ((val1, val2), (val1, val2), ...)
Run Code Online (Sandbox Code Playgroud)
我想选择两列在一组对中的数据。
如果可能,我想避免使用子查询。
给定一个users包含两个字段的表:id和email。
select id, email as electronic_mail
from (
select id, email
from users
) t
where electronic_mail = ''
Run Code Online (Sandbox Code Playgroud)
Postgres 抱怨说:
Run Code Online (Sandbox Code Playgroud)ERROR: column "electronic_mail" does not exist
这个例子只是为了说明出现的问题。我的实际情况更复杂,我遍历 json 列中的元素数组,从每个元素中获取一个标量值。(如果有帮助,我可以分享一些代码。)
我真的不明白会有什么并发症,可能我不知道什么。我的印象是可以在WHERE子句中使用别名列而没有问题?
我有一个使用WHERE子句的查询,我碰巧在这个表的许多查询中使用了完全相同的WHERE子句(等)。
查询是:
SELECT
DATENAME(DW, [AtDateTime]) AS [Day of Week]
,COUNT(*) AS [Number of Searches]
,CAST(CAST(COUNT(*) AS DECIMAL(10, 2))
/ COUNT(DISTINCT CONVERT(DATE, [AtDateTime])) AS DECIMAL(10, 2))
AS [Average Searches per Day]
,SUM(CASE WHEN [NumFound] = 0 THEN 1 ELSE 0 END)
AS [Number of Searches with no Results]
,CAST(CAST(SUM(CASE WHEN [NumFound] = 0 THEN 1 ELSE 0 END)
AS DECIMAL(10, 2)) / COUNT(*) AS DECIMAL(10, 4))
AS [Percent of Searches with no Results] …Run Code Online (Sandbox Code Playgroud) 我需要能够从具有数千万行的表中找到缺失的元素,并且有一个BINARY(64)列的主键(这是要计算的输入值)。这些值大多按顺序插入,但有时我想重用已删除的先前值。用IsDeleted列修改已删除的记录是不可行的,因为有时插入的行比当前存在的行高数百万个值。这意味着示例数据将类似于:
KeyCol : BINARY(64)
0x..000000000001
0x..000000000002
0x..FFFFFFFFFFFF
Run Code Online (Sandbox Code Playgroud)
因此在0x000000000002和之间插入所有缺失值0xFFFFFFFFFFFF是不可行的,使用的时间和空间量将是不可取的。本质上,当我运行算法时,我希望它返回0x000000000003,这是第一个开口。
我在 C# 中提出了一个二进制搜索算法,它将查询数据库中位置的每个值i,并测试该值是否是预期的。对于上下文,我可怕的算法:https : //codereview.stackexchange.com/questions/174498/binary-search-for-a-missing-or-default-value-by-a-given-formula
例如,该算法将在具有 100,000,000 个项目的表上运行 26-27 个 SQL 查询。(这看起来并不多,但它会非常频繁地发生。)目前,该表中大约有 50,000,000 行,性能变得很明显。
我的第一个替代想法是将其转换为存储过程,但这有其自身的障碍。(我必须编写一个BINARY(64) + BINARY(64)算法,以及大量其他东西。)这会很痛苦,但并非不可行。我也考虑过实现基于的翻译算法ROW_NUMBER,但我对此有一种非常糟糕的直觉。(BIGINT对于这些值,A几乎不够大。)
我愿意接受其他建议,因为我真的需要尽快解决这个问题。值得一提的是,C# 查询选择的唯一列是KeyCol,其他列与此部分无关。
此外,对于它的价值,获取适当记录的当前查询是这样的:
SELECT [KeyCol]
FROM [Table]
ORDER BY [KeyCol] ASC
OFFSET <VALUE> ROWS FETCH FIRST 1 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)
<VALUE> …
我正在研究使用动态查询根据用户输入执行选择语句的应用程序,在与 DBA 讨论安全性之后,他们希望我将动态选择语句转换为存储过程。
我已经使用 MSSQL 构建了动态 sql,但我不知道如何将其转换为 Oracle SQL。
CREATE PROCEDURE GetCustomer
@FirstN nvarchar(20) = NULL,
@LastN nvarchar(20) = NULL,
@CUserName nvarchar(10) = NULL,
@CID nvarchar(15) = NULL as
DECLARE @sql nvarchar(4000),
SELECT @sql = 'C_FirstName, C_LastName, C_UserName, C_UserID ' +
'FROM CUSTOMER ' +
'WHERE 1=1 ' +
IF @FirstN IS NOT NULL
SELECT @sql = @sql + ' AND C_FirstName like @FirstN '
IF @LastN IS NOT NULL
SELECT @sql = @sql + ' AND C_LastName like @LastN …Run Code Online (Sandbox Code Playgroud) 我想使用 TABLESAMPLE 从 PostgreSQL 满足特定条件的行中随机采样。
这运行良好:
select * from customers tablesample bernoulli (1);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何将条件嵌入脚本中。例如这个
select * from customers where last_name = 'powell' tablesample bernoulli (1);
Run Code Online (Sandbox Code Playgroud)
抛出这个错误:
SQL 错误 [42601]:错误:“tablesample”位置或附近的语法错误
:71
案例 1 - 在 where 子句中使用 OR 运算符的单个查询:
select * from users where name='smith' or nick='smith' (using index_merge )
Run Code Online (Sandbox Code Playgroud)
案例 2 - 在 where 子句中使用 equals 运算符的多个查询:
select * from users where name='smith'; (using single index);
select * from users where nick='smith'; (using single index);
Run Code Online (Sandbox Code Playgroud)
问:在案例 2 中是否有任何性能损失?
我有一个包含这些字段的表结果:
每个 number_* 列可以包含一个从 01 到 90 的数字。
我有一个带有 90 个复选框的搜索表单。用户最多可以勾选 5 个复选框。
一旦用户选择 n 复选框,我需要构建一个查询来查找包含所有这些值的行,但数字可以位于五列中的任何一列。
例子:
用户勾选复选框 02、12 和 20。我需要检索所有三个数字的所有行,但我的数字可以在任何 number_* 列中。20 可以在 number_one 列中,02 可以在 number_three 列中,12 可以在 number_four 列中。如何构建此查询?
另外,使用一列而不是五列会更好吗?结果表:
列号包含 02-12-20-57-84,其中 - 是分隔符。
示例:用户勾选复选框 02、12 和 20。所以我的查询将是
SELECT *
FROM results
WHERE numbers LIKE "%02%"
AND numbers LIKE "%12%"
AND numbers LIKE "%20%";
Run Code Online (Sandbox Code Playgroud)
更新:我目前正在使用 MySQL 进行此设置:
在 MySQL 中使用下表:
CREATE TABLE bob(foo ENUM('a','b','c'));
INSERT INTO bob (foo) VALUES ('a'),('b'),('c'),('a'),('a');
SELECT * FROM bob WHERE foo >= 2;
+------+
| foo |
+------+
| b |
| c |
+------+
Run Code Online (Sandbox Code Playgroud)
使用 PostGres 中的下表:
CREATE TYPE stuff AS ENUM ('a', 'b', 'c');
INSERT INTO bob (foo) VALUES ('a'), ('b'), ('b'), ('c'), ('c');
SELECT * FROM bob WHERE foo > 2;
(HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.) …Run Code Online (Sandbox Code Playgroud) 我很难弄清楚如何实现这一目标。我知道如何用 C# 实现它,但不知道如何用 SQL 实现。
假设我有下表:
| ID | 姓名 | 路由ID |
|---|---|---|
| 1 | 鲍勃 | 1001 |
| 2 | 鲍勃 | 1002 |
| 3 | 安娜 | 1001 |
| 4 | 吉姆 | 1001 |
| 5 | 伊莱 | 1001 |
我想返回整个表,并用一个额外的列显示routeID按名称出现的总次数,所以where name='Bob'看起来像:
| ID | 姓名 | 路由ID | 全部的 |
|---|---|---|---|
| 1 | 鲍勃 | 1001 | 4 |
| 2 | 鲍勃 | 1002 | 1 |
但是,如果我写类似的东西
declare @ct as nvarchar(5)
set @ct = (SELECT COUNT(RouteId) from <table>)
select *, @ct
from <table>
where name = 'Bob'
Run Code Online (Sandbox Code Playgroud)
我得到所有路线 ID 的总数,而不仅仅是行中显示的路线 ID。
我尝试查看计算列,但据我所知它不支持这种类型的查询。
有人能指出我正确的方向吗?