连接两个表时,以第一行然后第二行为例

时间:2019-01-18 14:02:12

标签: sql sql-server tsql

上下文:

这是一个简化。我将使用一个简单的购物车/产品类比。
乔将3个TunaCan放入购物车。 “表A”具有3行。保存产品和购物车的信息。

目前,它们是随机的TunaCan。在他到达杂货店结账之前,我们不会知道他们的序列。

在付款时,我们需要将产品的每一行与我们扫描过的“表B”序列之一相关联。
序列-购物车产品是一对唯一的商品,两个产品不能具有相同的序列。
如果序列号少于产品,则剩余产品将具有默认序列“ DefaultValue”

表A:CartProduct(字符串产品,整数CartID)

TunaCan 1   
TunaCan 1
TunaCan 1

表B:ScannedProduct(字符串序列号,产品)

Foo         TunaCan
Bar         TunaCan
FooBar      TunaCan

预期结果可能是:

TunaCan     1   Foo 
TunaCan     1   Bar
TunaCan     1   FooBar

“可以”,因为一组3个元素有7种可能的组合。

在LinQ中,我将使用索引访问第二个收集中的行

var result = TableA.Select((x,i)=> new{ x.propertie, TableB[i]})

2 个答案:

答案 0 :(得分:2)

如果我正确理解了您的问题,则可以尝试为CartProductScannedProduct表编号,然后将它们加入该编号:

-- Tables
CREATE TABLE #CartProduct (
    Product varchar(100), 
    CartID int
)
INSERT INTO #CartProduct 
    (Product, CartID)
VALUES 
    ('TunaCan', 1),   
    ('TunaCan', 1),
    ('TunaCan', 1)

CREATE TABLE #ScannedProduct(
    Serial varchar(10),
    Product varchar(100)
)
INSERT INTO #ScannedProduct 
    (Serial, Product)
VALUES 
    ('Foo', 'TunaCan'),
    ('Bar', 'TunaCan'),
    ('FooBar', 'TunaCan')

-- Statement 
;WITH cte1 AS (
    SELECT 
        Product, 
        CartID,
        ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Product) Rn
    FROM #CartProduct
), cte2 AS (
    SELECT 
        Product, 
        Serial,
        ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Product) Rn
    FROM #ScannedProduct
)
SELECT
    cte1.Product Product,
    cte1.CartID CartID,
    ISNULL(cte2.Serial, 'Default value') Serial
FROM cte1
LEFT JOIN cte2 ON (cte1.Product = cte2.Product)  AND (cte1.Rn = cte2.Rn)

输出:

Product CartID  Serial
TunaCan 1       Bar
TunaCan 1       Foo
TunaCan 1       FooBar

答案 1 :(得分:0)

您需要交叉连接: 从A a交叉连接B b中选择a.stringproduct,a.cartID,b.product