SQL。如何比较两个 table 的值,并报告每行结果
SQL. how to compare values and from two table, and report per-row results
我有两个 Table。
table一个
id name Size
===================
1 Apple 7
2 Orange 15
3 Banana 22
4 Kiwi 2
5 Melon 28
6 Peach 9
和TableB
id size
==============
1 14
2 5
3 31
4 9
5 1
6 16
7 7
8 25
我想要的结果是(向 Table A 添加一列,这是 Table B 中 size 小于的行数尺寸 Table A)
id name Size Num.smaller.in.B
==============================
1 Apple 7 2
2 Orange 15 5
3 Banana 22 6
4 Kiwi 2 1
5 Melon 28 7
6 Peach 9 3
Table A 和 B 都很大。有没有聪明的方法来做到这一点。谢谢
没有什么聪明的方法可以做到这一点,您只需要像这样连接表格:
select a.*, b.size
from TableA a join TableB b on a.id = b.id
要提高性能,您需要在 id 列上建立索引。
使用这个查询很有帮助
SELECT id,
name,
Size,
(Select count(*) From TableB Where TableB.size<Size)
FROM TableA
@Ritesh 的解决方案完全正确,另一个类似的解决方案是使用 CROSS JOIN 如下所示
use tempdb
create table dbo.A (id int identity, name varchar(30), size int );
create table dbo.B (id int identity, size int);
go
insert into dbo.A (name, size)
values ('Apple', 7)
,('Orange', 15)
,('Banana', 22)
,('Kiwi', 2 )
,('Melon', 28)
,('Peach', 6 )
insert into dbo.B (size)
values (14), (5),(31),(9),(1),(16), (7),(25)
go
-- using cross join
select a.*, t.cnt
from dbo.A
cross apply (select cnt=count(*) from dbo.B where B.size < A.size) T(cnt)
可能
select
id,
name,
a.Size,
sum(cnt) as sum_cnt
from
a inner join
(select size, count(*) as cnt from b group by size) s on
s.size < a.size
group by id,name,a.size
如果您使用的是大型 tables。索引 table b
的 size
字段可能会有所帮助。我还假设 table B
中的值收敛,除了你想计算它们之外,还有许多你不关心的重复项。
试试这个查询
SELECT
A.id,A.name,A.size,Count(B.size)
from A,B
where A.size>B.size
group by A.size
order by A.id;
获得结果的标准方法涉及非等值连接,这将是 Explain 中的 产品连接。首先复制 20,000 行,然后是 7,000,000 * 20,000 次比较和计数之前的巨大中间假脱机。
有一个基于 OLAP 函数的解决方案通常非常有效:
SELECT dt.*,
-- Do a cumulative count of the rows of table #2
-- sorted by size, i.e. count number of rows with a size #2 less size #1
Sum(CASE WHEN NAME = '' THEN 1 ELSE 0 end)
Over (ORDER BY SIZE, NAME DESC ROWS Unbounded Preceding)
FROM
( -- mix the rows of both tables, an empty name indicates rows from table #2
SELECT id, name, size
FROM a
UNION ALL
SELECT id, '', size
FROM b
) AS dt
-- only return the rows of table #1
QUALIFY name <> ''
如果 table 中有多个相同大小的行 #2 你最好在 Union 之前计数以减少大小:
SELECT dt.*,
-- Do a cumulative sum of the counts of table #2
-- sorted by size, i.e. count number of rows with a size #2 less size #1
Sum(CASE WHEN NAME ='' THEN id ELSE 0 end)
Over (ORDER BY SIZE, NAME DESC ROWS Unbounded Preceding)
FROM
( -- mix the rows of both tables, an empty name indicates rows from table #2
SELECT id, name, size
FROM a
UNION ALL
SELECT Count(*), '', SIZE
FROM b
GROUP BY SIZE
) AS dt
-- only return the rows of table #1
QUALIFY NAME <> ''
我有两个 Table。 table一个
id name Size
===================
1 Apple 7
2 Orange 15
3 Banana 22
4 Kiwi 2
5 Melon 28
6 Peach 9
和TableB
id size
==============
1 14
2 5
3 31
4 9
5 1
6 16
7 7
8 25
我想要的结果是(向 Table A 添加一列,这是 Table B 中 size 小于的行数尺寸 Table A)
id name Size Num.smaller.in.B
==============================
1 Apple 7 2
2 Orange 15 5
3 Banana 22 6
4 Kiwi 2 1
5 Melon 28 7
6 Peach 9 3
Table A 和 B 都很大。有没有聪明的方法来做到这一点。谢谢
没有什么聪明的方法可以做到这一点,您只需要像这样连接表格:
select a.*, b.size
from TableA a join TableB b on a.id = b.id
要提高性能,您需要在 id 列上建立索引。
使用这个查询很有帮助
SELECT id,
name,
Size,
(Select count(*) From TableB Where TableB.size<Size)
FROM TableA
@Ritesh 的解决方案完全正确,另一个类似的解决方案是使用 CROSS JOIN 如下所示
use tempdb
create table dbo.A (id int identity, name varchar(30), size int );
create table dbo.B (id int identity, size int);
go
insert into dbo.A (name, size)
values ('Apple', 7)
,('Orange', 15)
,('Banana', 22)
,('Kiwi', 2 )
,('Melon', 28)
,('Peach', 6 )
insert into dbo.B (size)
values (14), (5),(31),(9),(1),(16), (7),(25)
go
-- using cross join
select a.*, t.cnt
from dbo.A
cross apply (select cnt=count(*) from dbo.B where B.size < A.size) T(cnt)
可能
select
id,
name,
a.Size,
sum(cnt) as sum_cnt
from
a inner join
(select size, count(*) as cnt from b group by size) s on
s.size < a.size
group by id,name,a.size
如果您使用的是大型 tables。索引 table b
的 size
字段可能会有所帮助。我还假设 table B
中的值收敛,除了你想计算它们之外,还有许多你不关心的重复项。
试试这个查询
SELECT
A.id,A.name,A.size,Count(B.size)
from A,B
where A.size>B.size
group by A.size
order by A.id;
获得结果的标准方法涉及非等值连接,这将是 Explain 中的 产品连接。首先复制 20,000 行,然后是 7,000,000 * 20,000 次比较和计数之前的巨大中间假脱机。
有一个基于 OLAP 函数的解决方案通常非常有效:
SELECT dt.*,
-- Do a cumulative count of the rows of table #2
-- sorted by size, i.e. count number of rows with a size #2 less size #1
Sum(CASE WHEN NAME = '' THEN 1 ELSE 0 end)
Over (ORDER BY SIZE, NAME DESC ROWS Unbounded Preceding)
FROM
( -- mix the rows of both tables, an empty name indicates rows from table #2
SELECT id, name, size
FROM a
UNION ALL
SELECT id, '', size
FROM b
) AS dt
-- only return the rows of table #1
QUALIFY name <> ''
如果 table 中有多个相同大小的行 #2 你最好在 Union 之前计数以减少大小:
SELECT dt.*,
-- Do a cumulative sum of the counts of table #2
-- sorted by size, i.e. count number of rows with a size #2 less size #1
Sum(CASE WHEN NAME ='' THEN id ELSE 0 end)
Over (ORDER BY SIZE, NAME DESC ROWS Unbounded Preceding)
FROM
( -- mix the rows of both tables, an empty name indicates rows from table #2
SELECT id, name, size
FROM a
UNION ALL
SELECT Count(*), '', SIZE
FROM b
GROUP BY SIZE
) AS dt
-- only return the rows of table #1
QUALIFY NAME <> ''