按查询删除组中的子查询
Remove subquery in group by query
我有以下查询。它按预期工作。但是它有一个子查询。有什么办法可以优化吗?
SELECT Foo,
count(*)
FROM
(SELECT Foo
FROM MyTable
GROUP BY Foo,
Bar,
Baz) AS Subquery
GROUP BY Foo
为了上下文
它正在处理的数据集如下:
| Foo | Bar | Baz |
|-----|-----|-----|
| a | 1 | |
| a | | 2 |
| b | 3 | |
| b | 3 | |
预期结果是:
| Foo | Count |
|-----|-------|
| a | 2 |
| b | 1 |
文字说明。或者尝试。
我想获得每个 Foo 的不同 Bar 和 Baz 的数量。
根据问题的编辑...
SELECT Foo, Count(distinct isnull(foo,'-')+isnull(bar,'-')+isnull(baz,'-'))
FROM MyTable
group by foo
如果空格字符不同(即您的数据不包括 -
,这与子查询的功能相同
https://data.stackexchange.com/Whosebug/query/372553/for-question-32992867
我想你想要这个:
SELECT Foo, count(*)
FROM MyTable
GROUP BY Foo, Bar, Baz
你可能想要这个:
SELECT Foo, Count(*) OVER (Partition By Foo, Bar, Baz)
FROM MyTable
如果这些没有给您想要的结果,请解释原因
免责声明:
这纯粹是为了好玩的解决方案,它不是 100% 可靠的,并且在发生碰撞时可能会失败。我 post 它只是因为我试图在没有子查询的情况下获得解决方案。它不会更快,所以请不要在生产系统中使用它。
我假设 Bar
xor Baz
.
列中可以有一个值
CREATE TABLE #MyTable(Foo VARCHAR(100), Bar VARCHAR(10), Baz VARCHAR(10));
INSERT INTO #MyTable(Foo, Bar, Baz)
VALUES ('a', '1', NULL), ('a', NULL ,'2'), ('b', '3', NULL),
('a', '2', NULL), ('a', NULL ,'1'), ('b', '3', NULL),
('a', NULL, '2'), ('a', NULL ,'1'), ('b', '4', NULL),
('a', NULL, '1'), ('a', NULL ,'2'), ('b', '7', NULL);
SELECT Foo, COUNT(DISTINCT
CAST(CHECKSUM(Bar, Baz) AS BIGINT) +
CAST(CHECKSUM(Baz, Bar) AS BIGINT) +
CAST(CHECKSUM(REVERSE(Bar),REVERSE(Baz)) AS BIGINT) +
CAST(CHECKSUM(REVERSE(Baz),REVERSE(Bar)) AS BIGINT))
FROM #MyTable
GROUP BY Foo;
编辑:
如果 ('a', NULL, 1)
和 ('a', 1, NULL)
应该不同,您需要使用:
SELECT Foo, COUNT(DISTINCT
CAST(CHECKSUM(Bar, Baz) AS BIGINT) +
CAST(CHECKSUM(REVERSE(Bar),REVERSE(Baz)) AS BIGINT))
FROM #MyTable
GROUP BY Foo
任何想法如何改进它或为什么它 "sucks" 赞赏。
没有办法优化它,你可以用不同的方式写它,但不会更快。可以这样改写,但是不能改写,避免subselect:
SELECT Foo,
count(*)
FROM
(SELECT distinct Foo, bar, baz
FROM @t
) AS Subquery
GROUP BY Foo
我有以下查询。它按预期工作。但是它有一个子查询。有什么办法可以优化吗?
SELECT Foo,
count(*)
FROM
(SELECT Foo
FROM MyTable
GROUP BY Foo,
Bar,
Baz) AS Subquery
GROUP BY Foo
为了上下文
它正在处理的数据集如下:
| Foo | Bar | Baz |
|-----|-----|-----|
| a | 1 | |
| a | | 2 |
| b | 3 | |
| b | 3 | |
预期结果是:
| Foo | Count |
|-----|-------|
| a | 2 |
| b | 1 |
文字说明。或者尝试。
我想获得每个 Foo 的不同 Bar 和 Baz 的数量。
根据问题的编辑...
SELECT Foo, Count(distinct isnull(foo,'-')+isnull(bar,'-')+isnull(baz,'-'))
FROM MyTable
group by foo
如果空格字符不同(即您的数据不包括 -
https://data.stackexchange.com/Whosebug/query/372553/for-question-32992867
我想你想要这个:
SELECT Foo, count(*)
FROM MyTable
GROUP BY Foo, Bar, Baz
你可能想要这个:
SELECT Foo, Count(*) OVER (Partition By Foo, Bar, Baz)
FROM MyTable
如果这些没有给您想要的结果,请解释原因
免责声明:
这纯粹是为了好玩的解决方案,它不是 100% 可靠的,并且在发生碰撞时可能会失败。我 post 它只是因为我试图在没有子查询的情况下获得解决方案。它不会更快,所以请不要在生产系统中使用它。
我假设 Bar
xor Baz
.
CREATE TABLE #MyTable(Foo VARCHAR(100), Bar VARCHAR(10), Baz VARCHAR(10));
INSERT INTO #MyTable(Foo, Bar, Baz)
VALUES ('a', '1', NULL), ('a', NULL ,'2'), ('b', '3', NULL),
('a', '2', NULL), ('a', NULL ,'1'), ('b', '3', NULL),
('a', NULL, '2'), ('a', NULL ,'1'), ('b', '4', NULL),
('a', NULL, '1'), ('a', NULL ,'2'), ('b', '7', NULL);
SELECT Foo, COUNT(DISTINCT
CAST(CHECKSUM(Bar, Baz) AS BIGINT) +
CAST(CHECKSUM(Baz, Bar) AS BIGINT) +
CAST(CHECKSUM(REVERSE(Bar),REVERSE(Baz)) AS BIGINT) +
CAST(CHECKSUM(REVERSE(Baz),REVERSE(Bar)) AS BIGINT))
FROM #MyTable
GROUP BY Foo;
编辑:
如果 ('a', NULL, 1)
和 ('a', 1, NULL)
应该不同,您需要使用:
SELECT Foo, COUNT(DISTINCT
CAST(CHECKSUM(Bar, Baz) AS BIGINT) +
CAST(CHECKSUM(REVERSE(Bar),REVERSE(Baz)) AS BIGINT))
FROM #MyTable
GROUP BY Foo
任何想法如何改进它或为什么它 "sucks" 赞赏。
没有办法优化它,你可以用不同的方式写它,但不会更快。可以这样改写,但是不能改写,避免subselect:
SELECT Foo,
count(*)
FROM
(SELECT distinct Foo, bar, baz
FROM @t
) AS Subquery
GROUP BY Foo