SQL加入连接表的第一行,第二行和第三行

时间:2010-10-29 04:22:11

标签: sql sql-server join

我需要在最终结果上显示一些来自连接的列。这些专栏分为3组,例如:

name_1, addr_1, prefecture_1, price_1,
name_2, addr_2, prefecture_2, price_2,
name_3, addr_3, prefecture_3, price_3

这三个组来自一个连接,根据排序键 carrier_cd2 ,它只能返回3个记录。 _1组是第一行,_2组是第二行,_3是第三行。

我的问题与this SO question几乎相同,但我需要3条记录而不是2条。

我提出了我的初始SQL查询:

SELECT
    inner_t12.contract_no,
    inner_t13.carrier_cd2,
    inner_t13.addr,
    inner_t13.prefecture,
    inner_t13_2.carrier_cd2,
    inner_t13_2.addr,
    inner_t13_2.prefecture,
    inner_t13_3.carrier_cd2,
    inner_t13_3.addr,
    inner_t13_3.prefecture
FROM
    処分業者契約マスタ inner_t12
    LEFT OUTER JOIN 処分契約委託運搬業者マスタ inner_t13
        ON inner_t12.contract_no = inner_t13.contract_no
    JOIN 処分契約委託運搬業者マスタ inner_t13_2
        ON inner_t13_2.contract_no = inner_t13.contract_no
        AND inner_t13_2.carrier_cd2 > inner_t13.carrier_cd2
    JOIN 処分契約委託運搬業者マスタ inner_t13_3
        ON inner_t13_3.contract_no = inner_t13.contract_no
        AND inner_t13_3.carrier_cd2 > inner_t13_2.carrier_cd2

The screenshot

它返回最终结果集上的所需行,但是它需要保留为外部联接,这样即使连接不生成所需的3行,它仍然会显示行,即使是2或1,也不应该有效改为显示NULL。

希望你能给出一些暗示。

先谢谢。

SQL Server 2005 Express

3 个答案:

答案 0 :(得分:1)

如果我理解这个问题,我认为你正在寻找这个问题。将左连接内的两个内连接括起来

FROM
    inner_t12
    LEFT OUTER JOIN inner_t13
    (    
    INNER JOIN  inner_t13_2
        ON inner_t13_2.contract_no = inner_t13.contract_no
        AND inner_t13_2.carrier_cd2 > inner_t13.carrier_cd2
    INNER JOIN  inner_t13_3
        ON inner_t13_3.contract_no = inner_t13.contract_no
        AND inner_t13_3.carrier_cd2 > inner_t13_2.carrier_cd2
)
ON inner_t12.contract_no = inner_t13.contract_no

答案 1 :(得分:0)

如果你的意思是只有3行(3条记录), 只需在TOP 3声明中添加“SELECT”即可 见下文。

SELECT
    TOP 3
    inner_t12.contract_no,
    inner_t13.carrier_cd2,
    inner_t13.addr,
    inner_t13.prefecture,
    inner_t13_2.carrier_cd2,
    inner_t13_2.addr,
    inner_t13_2.prefecture,
    inner_t13_3.carrier_cd2,
    inner_t13_3.addr,
    inner_t13_3.prefecture
FROM
    処分業者契約マスタ inner_t12
    LEFT OUTER JOIN 処分契約委託運搬業者マスタ inner_t13
        ON inner_t12.contract_no = inner_t13.contract_no
    JOIN 処分契約委託運搬業者マスタ inner_t13_2
        ON inner_t13_2.contract_no = inner_t13.contract_no
        AND inner_t13_2.carrier_cd2 > inner_t13.carrier_cd2
    JOIN 処分契約委託運搬業者マスタ inner_t13_3
        ON inner_t13_3.contract_no = inner_t13.contract_no
        AND inner_t13_3.carrier_cd2 > inner_t13_2.carrier_cd2

答案 2 :(得分:0)

我想我解决了(有点)。我所做的是在JOIN的ON子句上使用ROW_NUMBER和OVER()。

use OurProjectDb
go

SELECT
    t12.disposal_cd,

    t21_1.name_kanji AS name_kanji_1,
    t13_1.prefecture AS prefecture_1,
    t13_1.addr AS addr_1,
    t13_1.permission_no AS permission_no_1,
    t13_1.vehicle_type AS vehicle_type_1,
    t13_1.transport_price AS transport_price_1,

    t21_2.name_kanji AS name_kanji_2,
    t13_2.prefecture AS prefecture_2,
    t13_2.addr AS addr_2,
    t13_2.permission_no AS permission_no_2,
    t13_2.vehicle_type AS vehicle_type_2,
    t13_2.transport_price AS transport_price_2,

    t21_3.name_kanji AS name_kanji_3,
    t13_3.prefecture AS prefecture_3,
    t13_3.addr AS addr_3,
    t13_3.permission_no AS permission_no_3,
    t13_3.vehicle_type AS vehicle_type_3,
    t13_3.transport_price AS transport_price_3
FROM
    処分業者契約マスタ t12
    LEFT OUTER JOIN
    (
        処分契約委託運搬業者マスタ t13_1
        LEFT OUTER JOIN 委託運搬業者マスタ t21_1 ON t13_1.carrier_cd2 = t21_1.carrier_cd2
    )
    ON t13_1.contract_no = t12.contract_no AND t13_1.carrier_cd2 = (
        SELECT TOP 1
            inner_t13_1.carrier_cd2
        FROM
            処分契約委託運搬業者マスタ inner_t13_1
        WHERE
            inner_t13_1.contract_no = t12.contract_no
        ORDER BY
            inner_t13_1.carrier_cd2 ASC
    )
    LEFT OUTER JOIN
    (
        処分契約委託運搬業者マスタ t13_2
        LEFT OUTER JOIN 委託運搬業者マスタ t21_2 ON t13_2.carrier_cd2 = t21_2.carrier_cd2
    )
    ON t13_2.contract_no = t12.contract_no AND t13_2.carrier_cd2 = (
        SELECT
            carrier_cd2
        FROM
        (
            SELECT TOP 2
                ROW_NUMBER() OVER (ORDER BY inner_t13_2.carrier_cd2) AS row_num,
                inner_t13_2.carrier_cd2
            FROM
                処分契約委託運搬業者マスタ inner_t13_2
            WHERE
                inner_t13_2.contract_no = t12.contract_no
            ORDER BY
                inner_t13_2.carrier_cd2
        ) top2join
        WHERE
            row_num = 2
    )
    LEFT OUTER JOIN
    (
        処分契約委託運搬業者マスタ t13_3
        LEFT OUTER JOIN 委託運搬業者マスタ t21_3 ON t13_3.carrier_cd2 = t21_3.carrier_cd2
    )
    ON t13_3.contract_no = t12.contract_no AND t13_3.carrier_cd2 = (
        SELECT
            carrier_cd2
        FROM
        (
            SELECT TOP 3
                ROW_NUMBER() OVER (ORDER BY inner_t13_3.carrier_cd2) AS row_num,
                inner_t13_3.carrier_cd2
            FROM
                処分契約委託運搬業者マスタ inner_t13_3
            WHERE
                inner_t13_3.contract_no = t12.contract_no
            ORDER BY
                inner_t13_3.carrier_cd2
        ) top3join
        WHERE
            row_num = 3
    )