Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL Server中获取相互匹配_Sql_Sql Server - Fatal编程技术网

在SQL Server中获取相互匹配

在SQL Server中获取相互匹配,sql,sql-server,Sql,Sql Server,我想把买家和卖家配对。我这样做是为了让它尽可能简单 我有一张桌子:tmpSales。在其中,我有一个TransID、BuyerID、SellerID、Item和Date 有时买方也是卖方,反之亦然 我想要的是一张记录,一个买主卖给一个卖主,同一个卖主卖给同一个买主 我有一个查询,它可以正常工作: SELECT * FROM [dbo].[tmpSales] T1 INNER JOIN [dbo].[tmpSales] T2 ON T1.[BuyerID] = T2.[SellerID] AND

我想把买家和卖家配对。我这样做是为了让它尽可能简单

我有一张桌子:tmpSales。在其中,我有一个TransID、BuyerID、SellerID、Item和Date

有时买方也是卖方,反之亦然

我想要的是一张记录,一个买主卖给一个卖主,同一个卖主卖给同一个买主

我有一个查询,它可以正常工作:

SELECT *
FROM [dbo].[tmpSales] T1
INNER JOIN [dbo].[tmpSales] T2
ON T1.[BuyerID] = T2.[SellerID]
AND T2.[BuyerID] = T1.[SellerID]
但是,它为每个匹配返回2条记录。有没有办法在BuyerID和SellerID都存在的情况下返回一条记录

示例数据如下所示:

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  
在本例中,我可以看到10012和10032都相互出售和购买,就像10012和11111一样。我只想要这样的东西:

ID1             ID2
10012           10032
10012           11111
数据将不断增长,因此它必须是动态的,也就是说,我不能在代码中添加类似的内容,其中BuyerID='10012'


编辑:实际上,我想做的是将其作为一个视图或存储过程,并向其传递两个ID,让它告诉我是否存在相互匹配。

通过选择第一个,您可以轻松地将select中的数据限制为一种方式,如下所示:

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]

因此,这样一来,拥有更大买家ID的买家始终是第二个买家,并且您也可以在一个过程中使用类似的逻辑。

您可以使用以下查询来检索所有相互映射

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)
如果只想检查指定的对,也可以这样做

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)

这在MySql中是存在的,但同样的原则也适用

此查询获取两个人之间进行的交易的所有不同用户,其中他们都是不同交易中的买方和卖方。由于这包括所有交易,每个参与者将被列为两次,一次作为买方,一次作为卖方,如果两个方向都有一次以上的销售,则会被列为更多次,而不带明显标记

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
;
这将提供以下行:

+ ----------- + ----------- +
| party1      | party2      |
+ ----------- + ----------- +
| 10032       | 10012       |
| 10012       | 11111       |
| 10012       | 10032       |
| 11111       | 10012       |
+ ----------- + ----------- +
4 rows
+ ----------- + ----------- +
| party1      | party2      |
+ ----------- + ----------- +
| 10032       | 10012       |
| 11111       | 10012       |
+ ----------- + ----------- +
2 rows
添加下面的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
;
这将提供以下行:

+ ----------- + ----------- +
| party1      | party2      |
+ ----------- + ----------- +
| 10032       | 10012       |
| 10012       | 11111       |
| 10012       | 10032       |
| 11111       | 10012       |
+ ----------- + ----------- +
4 rows
+ ----------- + ----------- +
| party1      | party2      |
+ ----------- + ----------- +
| 10032       | 10012       |
| 11111       | 10012       |
+ ----------- + ----------- +
2 rows
为完整起见,以下是整个示例:

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
;

啊。。。这是一个非常有趣的问题,有三个人比我先到这里。在任何情况下,我建议在数据集增长时将这些数据记录到表中,而不是在每次需要查看时都运行一个特别的查询,但是对于初始数据填充,这里是我收集的一个小光标。希望有帮助

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 ;

它实际上非常简单,要么使用CTE/派生表解决方案,要么使用WHERE EXISTS解决方案。再加上@TabAlleman所说的,以避免每次匹配获得两条记录,即买方1与卖方2,买方2与卖方1,只需使用WHERE子句断言BuyerId