简体   繁体   English

在SQL Server中获取相互匹配

[英]Getting mutual matches in SQL Server

I want to match up Buyers and Sellers. 我想配对买家和卖家。 I'm doing this to make it as simple as possible. 我这样做是为了使其尽可能简单。

I have a table: tmpSales. 我有一张桌子:tmpSales。 In it, I have a TransID, BuyerID, SellerID, Item and Date. 在其中,我有一个TransID,BuyerID,SellerID,商品和日期。

Sometimes buyers are sellers too, and vice versa. 有时买家也是卖家,反之亦然。

What I want is a record where a buyer sold to a seller and that same seller sold to that same buyer. 我想要的是一个记录,其中买方出售给卖方,而同一卖方出售给相同买方。

I've got this query, which works fine: 我有此查询,它工作正常:

SELECT *
FROM [dbo].[tmpSales] T1
INNER JOIN [dbo].[tmpSales] T2
ON T1.[BuyerID] = T2.[SellerID]
AND T2.[BuyerID] = T1.[SellerID]

However, it returns 2 records for each match. 但是,它为每个匹配返回2条记录。 Is there any way for this to return a single record, with both BuyerID and SellerID present? 有什么办法可以返回同时包含BuyerID和SellerID的单个记录?

Sample data would look like so: 样本数据如下所示:

TransID     BuyerID     SellerID      ItemID      Date
1           10012       10032          65         10/15/2014
2           11111       10012          120        12/15/2014
3           10032       10012          32         2/2/2015
4           11111       10032          30         2/10/2015
5           10012       11111          45         3/1/2015  

In this case, I can see that 10012 and 10032 both sold to and bought from each other, as did 10012 and 11111 . 在这种情况下,我可以看到1001210032彼此买卖,就像1001211111一样 I just want something like: 我只想要这样的东西:

ID1             ID2
10012           10032
10012           11111

The data will be ever growing, so it's got to be dynamic (ie I can't put anything like, "Where BuyerID = '10012'" into the code). 数据将不断增长,因此它必须是动态的(即,我不能在代码中添加“ Where BuyerID ='10012'”之类的内容)。

EDIT: Actually, what I want to do is make this a view or stored procedure and pass 2 IDs to it, and have it tell me whether or not there is a mutual match. 编辑:实际上,我要做的是使它成为视图或存储过程,并向其传递2个ID,并告诉我是否存在相互匹配。

You can easily limit the data in your select to be just one way by selecting which one is the first, like this: 您可以通过选择第一个数据轻松地将选择的数据限制为一种,例如:

SELECT *
FROM [dbo].[tmpSales] T1
INNER JOIN [dbo].[tmpSales] T2
ON T1.[BuyerID] = T2.[SellerID]
AND T2.[BuyerID] = T1.[SellerID]
AND T2.[BuyerID] > T1.[BuyerID]

So this way the one that has bigger buyer ID is always as the second one -- and you can have similar logic inside a procedure too. 因此,具有较大买方ID的那个总是第二个,而且您在过程中也可以有类似的逻辑。

You can use the following query to retrieve all the mutual map 您可以使用以下查询来检索所有相互映射

SELECT DISTINCT T.BuyerID AS ID1,T.SellerID AS ID2
FROM [dbo].[tmpSales] T
WHERE EXISTS (SELECT * 
              FROM [dbo].[tmpSales] T1
              WHERE T1.BuyerID = T.SellerId
                    AND T1.SellerID = T.BuyerID)

If you want to check only for a specified pair, you can also do like this 如果只想检查指定的一对,也可以这样

DECLARE @Id1 INT
DECLARE @Id2 INT
SELECT *
FROM [dbo].[tmpSales] T
WHERE T.BuyerID = @Id1
AND T.SellerID = @Id2
AND EXISTS (SELECT * 
            FROM [dbo].[tmpSales] T1
            WHERE T1.BuyerID = @Id2
                AND T1.SellerID = @Id1)

This is in MySql but the same principles apply. 这在MySql中,但适用相同的原理。

This query gets all of the distinct users for transactions made between two individuals where they've both been the buyer and the seller in different transactions. 此查询可获取在两个个人之间进行的交易的所有不同用户,他们在不同交易中既是买家又是卖家。 Since this includes all transactions each participant will be listed twice (once as the buyer and once as the seller -- and would be listed even more times with out the "distinct" if there was more than one sale in either direction). 由于这包括所有交易,每个参与者将被列出两次(一次作为买方,一次作为卖方-如果在任一方向上有多个销售,则将被列出更多次而没有“区别”)。

select
    distinct sale1.buyer_id party1, sale1.seller_id party2
from
    temp_sale sale1
    join temp_sale sale2 on sale1.buyer_id = sale2.seller_id and sale1.seller_id = sale2.buyer_id
;

This gives these rows: 这给出了这些行:

+ ----------- + ----------- +
| party1      | party2      |
+ ----------- + ----------- +
| 10032       | 10012       |
| 10012       | 11111       |
| 10012       | 10032       |
| 11111       | 10012       |
+ ----------- + ----------- +
4 rows

Adding the where clause below will get you the distinct set of individuals that have both bought and sold from each other. 在下面添加where子句将使您获得彼此不同的一组单独的个体。

select
    distinct sale1.buyer_id party1, sale1.seller_id party2
from
    temp_sale sale1
    join temp_sale sale2 on sale1.buyer_id = sale2.seller_id and sale1.seller_id = sale2.buyer_id
where 
    sale1.buyer_id > sale1.seller_id
;

This gives these rows: 这给出了这些行:

+ ----------- + ----------- +
| party1      | party2      |
+ ----------- + ----------- +
| 10032       | 10012       |
| 11111       | 10012       |
+ ----------- + ----------- +
2 rows

For completeness, here is the entire example: 为了完整起见,下面是整个示例:

use example;

drop table if exists temp_sale;

create table temp_sale (
    id int,
    buyer_id int,
    seller_id int,
    item_id int,
    date date
);

insert into temp_sale values (1, 10012, 10032, 65, '2014-10-15');
insert into temp_sale values (2, 11111, 10012, 120, '2014-12-15');
insert into temp_sale values (3, 10032, 10012, 32, '2015-02-02');
insert into temp_sale values (4, 11111, 10032, 30, '2015-02-10');
insert into temp_sale values (5, 10012, 11111, 45, '2015-03-01');

select
    distinct sale1.buyer_id party1, sale1.seller_id party2
from
    temp_sale sale1
    join temp_sale sale2 on sale1.buyer_id = sale2.seller_id and sale1.seller_id = sale2.buyer_id
;

select
    distinct sale1.buyer_id party1, sale1.seller_id party2
from
    temp_sale sale1
    join temp_sale sale2 on sale1.buyer_id = sale2.seller_id and sale1.seller_id = sale2.buyer_id
where 
    sale1.buyer_id > sale1.seller_id
;

Aw... this was such an interesting question that 3 people got here before me. 噢,这是一个很有趣的问题,三个人在我面前来到了这里。 In any case, I recommend logging this data to a table as the dataset grows rather than just running an ad-hoc query each time you want to see it, but for the initial data population, here's a gross little cursor I scraped together. 无论如何,我建议随着数据集的增长而将此数据记录到表中,而不是每次都想运行临时查询时都要记录,但是对于初始数据填充,这是我凑在一起的一个小光标。 Hope it helps! 希望能帮助到你!

if object_id(N'tempdb..#FindMe') is not null
    drop table #FindMe ;

if object_id(N'tempdb..#UniqueRelationships') is not null
    drop table #UniqueRelationships ;

create table #UniqueRelationships
    ( Id1 int,
    Id2 int );

declare @Table table 
    ([TransID] int not null 
    ,[BuyerID] int not null 
    ,[SellerID] int not null 
    ,[ItemID] int not null 
    ,[Date] date not null );

insert @table values 
    (1,10012,10032,65,'2014-10-15 00:00:00.0'),
    (2,11111,10012,120,'2014-12-15 00:00:00.0'),
    (3,10032,10012,32,'2015-02-02 00:00:00.0'),
    (4,11111,10032,30,'2015-02-10 00:00:00.0'),
    (5,10012,11111,45,'2015-03-01 00:00:00.0');

select 
    t1.BuyerID
    ,t1.SellerID
into #FindMe 
from @table t1
join @Table t2 on t1.BuyerID = t2.SellerID
  and t2.BuyerID = t1.SellerID ;

declare
    @IdA int,
    @IdB int;

declare FindMe cursor for
    select BuyerId, SellerId from #FindMe ;

open FindMe ;
fetch next from FindMe into @IdA, @IdB ;
while @@fetch_status = 0
begin
    if not exists( select 1 
                    from #UniqueRelationships 
                    where ( Id1 = @IdA
                      and Id2 = @IdB ) 
                    or ( Id2 = @IdA
                      and Id1 = @IdB ) )
    begin
        insert #UniqueRelationships 
            ( Id1, Id2 )
        select 
            @IdA
            ,@IdB
    end

    fetch next from FindMe into @IdA, @IdB ;
end ;
close FindMe ;
deallocate FindMe ;

select * from #UniqueRelationships ;

if object_id(N'tempdb..#FindMe') is not null
    drop table #FindMe ;

if object_id(N'tempdb..#UniqueRelationships') is not null
    drop table #UniqueRelationships ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM