2016-09-28 57 views
1

我有兩個表。 表阿SQL。如何比較兩個表中的值並報告每行結果

id name Size 
=================== 
1 Apple 7 
2 Orange 15 
3 Banana 22 
4 Kiwi 2 
5 Melon 28 
6 Peach 9 

而表B

id size 
============== 
1 14 
2 5 
3 31 
4 9 
5 1 
6 16 
7 7 
8 25 

我期望的結果將是(添加一列於表A,這是在表B具有大小較小的行數表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 

表A和B都非常大。有沒有一個聰明的方法來做到這一點。由於

+0

究竟是什麼*相當巨大*?有沒有任何類型的分組,或者它實際上是比較所有行? – dnoeth

+0

是桃子6還是9表a? – Beth

+0

@Beth。應該是9.對於錯字 –

回答

3

使用這種查詢是有幫助

SELECT id, 
name, 
Size, 
(Select count(*) From TableB Where TableB.size<Size) 
FROM TableA 
1

有這樣做的沒有更好的方式,你只需要連接表是這樣的:

select a.*, b.size 
from TableA a join TableB b on a.id = b.id 

爲了提高你需要對ID列的索引的性能。

+0

對不起,我忘了指定。讓我澄清一下,我想要一個信息列,它的表[B中的行數大於表A中的大小] –

+0

除了他不想加入id,他加入的大小小於大小在其他表中 – Beth

0

@Ritesh的解決方案是完全正確的,另一個類似的解決方案是使用如下圖所示

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) 
1

也許

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 

CROSS JOIN如果您正在用大桌子工作。索引表bsize字段可能有所幫助。我還假設表B中的值趨於一致,除了要計算它們之外,還有許多您不關心的重複項。

sqlfiddle

0

嘗試此查詢

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; 
2

標準的方式來獲得你的結果牽涉到非相等聯接,這將是一個產品中加入解釋。首先複製20000行,之後進行700萬* 20000比較,並在計數之前設置一個巨大的中間軸。

有基於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 <> '' 

如果有與表#相同尺寸2你最好的聯盟之前數減少尺寸多行:

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 <> '' 
相關問題