选择计算柱,是依赖于一个相关
-
18-09-2019 - |
题
我不做了很多SQL,并大部分时间,我做污物的操作。偶尔我会得到的东西更复杂一点。因此,这个问题可能是一个新手的问题,但我已经准备好了。我只是一直试图弄清楚这一点的时间,而且它已经没有用的。
因此,想象一下下面的表格结构:
> | ID | Col1 | Col2 | Col3 | .. | Col8 |
我想要选择ID和一个计算柱。计算列有一个范围在0-8和它所包含的匹配数量的查询。我也想要限制的结果设定为只包括行,有一定数目的比赛。
因此,从这一样本数据:
> | 1 | 'a' | 'b' | 1 | 2 |
> | 2 | 'b' | 'c' | 1 | 2 |
> | 3 | 'b' | 'c' | 4 | 5 |
> | 4 | 'x' | 'x' | 9 | 9 |
我想要查询在1列='a'或第2列='c'或Col3=1或Col4=5其中的计算结果>1和结果设定这样的:
> | ID | Cal |
> | 1 | 2 |
> | 2 | 2 |
> | 3 | 2 |
我使用的是T-SQL和SQL服务器2005年,如果它的事项,我不能改变该数据库架构。
我也宁愿保留它作为一个自立的查询并没有创建一个存储程序或临时表格。
解决方案
这个答案将与SQL2005年,使用CTE清理派生表一点。
WITH Matches AS
(
SELECT ID, CASE WHEN Col1 = 'a' THEN 1 ELSE 0 END +
CASE WHEN Col2 = 'c' THEN 1 ELSE 0 END +
CASE WHEN Col3 = 1 THEN 1 ELSE 0 END +
CASE WHEN Col4 = 5 THEN 1 ELSE 0 END AS Result
FROM Table1
WHERE Col1 = 'a' OR Col2 = 'c' OR Col3 = 1 OR Col4 = 5
)
SELECT ID, Result
FROM Matches
WHERE Result > 1
其他提示
这里有一个解决方案,利用一个事实,即布尔的比较返回整数1或0:
SELECT * FROM (
SELECT ID, (Col1='a') + (Col2='c') + (Col3=1) + (Col4=5) AS calculated
FROM MyTable
) q
WHERE calculated > 1;
注意,你有括号的比较,因为布尔 +
具有更高优先级 =
.还有,你必须把它所有的子查询,因为你通常不能使用别名列在 WHERE
条款的相同的查询。
它可能看起来像你也应该使用 WHERE
条款,在子查询限制其行,但在所有可能性,你们要结束一个完整的表格的扫描无论如何,所以它可能不是一个大胜利。另一方面,如果期望,这样一个限制会 大 减少数中的行查询的结果,那么这将会是有价值的。
重新Quassnoi的评论,如果你不能把布尔表达整数值,应该有一种方法,以地图布尔的条件,整数,即使是一位详细。例如:
SELECT * FROM (
SELECT ID,
CASE WHEN Col1='a' THEN 1 ELSE 0 END
+ CASE WHEN Col2='c' THEN 1 ELSE 0 END
+ CASE WHEN Col3=1 THEN 1 ELSE 0 END
+ CASE WHEN Col4=5 THEN 1 ELSE 0 END AS calculated
FROM MyTable
) q
WHERE calculated > 1;
这个查询索引更多的保:
SELECT id, SUM(match)
FROM (
SELECT id, 1 AS match
FROM mytable
WHERE col1 = 'a'
UNION ALL
SELECT id, 1 AS match
FROM mytable
WHERE col2 = 'c'
UNION ALL
SELECT id, 1 AS match
FROM mytable
WHERE col3 = 1
UNION ALL
SELECT id, 1 AS match
FROM mytable
WHERE col4 = 5
) q
GROUP BY
id
HAVING SUM(match) > 1
这只会是有效的,如果 所有 列正在寻找是,第一,索引,第二,具有较高的基数(许多不同的数值)。
看看这篇文章在我的博客的性能的详细信息:
不隶属于 StackOverflow