从多个表中选择并组合成单行临时表

Posted

技术标签:

【中文标题】从多个表中选择并组合成单行临时表【英文标题】:Select from multiple tables and combine into single row of temp table 【发布时间】:2016-05-02 21:12:19 【问题描述】:

我有三个使用相同结构的表(FuelRates_PetrolFuelRates_LPGFuelRates_Diesel):

| OrganisationID | Band1 | Band2 | Band3 | ModifiedDate        |
|----------------|-------|-------|-------|---------------------|
| 1              | 10    | 12    | 19    | 01/05/2016 19:23:21 |
| 2              | 11    | 12    | 20    | 02/05/2016 19:23:21 |

我需要创建一个存储过程,它将从每个表中选择具有匹配OrganisationID 的记录。每张表都会有一条匹配的记录。

然后我需要将结果组合成一个具有以下结构的临时表并返回:

| OrganisationID | Petrol_Band1 | Petrol_Band2 | Petrol_Band3 | LPG_Band1 | LPG_Band2 | LPG_Band3 | Diesel_Band1 | Diesel_Band2 | Diesel_Band3 | ModifiedDate        |
|----------------|--------------|--------------|--------------|-----------|-----------|-----------|--------------|--------------|--------------|---------------------|
| 1              | 10           | 12           | 19           | 10        | 12        | 19        | 10           | 12           | 19           | 01/05/2016 19:23:21 |

FuelRates_Petrol 表中的Band1 列应插入到FuelRates 临时表的Petrol_Band1 列中。其余列应遵循此约定以创建如上所示的单行。

SQL 不是我真正的包,但这是我的努力:

ALTER PROCEDURE [dbo].[FuelRates_RetrieveList] 
    @OrganisationID int
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    CREATE TABLE #FuelRates(
    OrganisationID int,
    Petrol_Band1 int, 
    Petrol_Band2 int,
    Petrol_Band3 int,
    LPG_Band1 int,
    LPG_Band2 int,
    LPG_Band3 int,
    Diesel_Band1 int,
    Diesel_Band2 int,
    Diesel_Band3 int,
    ModifiedDate DateTime)

    SELECT Band1 As Petrol_Band1, Band2 As Petrol_Band2, Band3 As Petrol_Band3, ModifiedDate, OrganisationID FROM [FuelRates_Petrol]
    WHERE OrganisationID = @OrganisationID
    INSERT INTO #FuelRates

    SELECT Band1 As LPG_Band1, Band2 As LPG_Band2, Band3 As LPG_Band3 FROM [FuelRates_LPG]
    WHERE OrganisationID = @OrganisationID
    INSERT INTO #FuelRates

    SELECT Band1 As Diesel_Band1, Band2 As Diesel_Band2, Band3 As Diesel_Band3 FROM [FuelRates_Diesel]
    WHERE OrganisationID = @OrganisationID
    INSERT INTO #FuelRates

    SELECT * FROM #FuelRates

    DROP TABLE #FuelRates
END

执行此操作时出现以下错误:

消息 213,级别 16,状态 1,过程 FuelRates_RetrieveList,第 33 行 插入错误:列名或提供的值的数量不匹配 表定义。

第 33 行是临时表创建块中的Diesel_Band1 int,

我使用的是 SQL Server 2005。

是什么导致了这个错误,我是否以正确的方式解决这个问题?

【问题讨论】:

【参考方案1】:

我知道它说错误位于第 33 行,您将其归因于 Diesel_Band1,但紧随其后的是消息:

插入错误:列名或提供的值的数量与表定义不匹配。

SQL Server 对已定义表的INSERT 方法是先放置插入语句。

当您没有以与定义的表完全相同的顺序插入确切数量的列时,您需要定义列和顺序。

INSERT INTO myTable (column1, column2, column3,...columnN)

将插入内容更改为以下内容:

INSERT INTO #FuelRates
    (Petrol_Band1, Petrol_Band2, Petrol_Band3, ModifiedDate, OrganisationID)
    SELECT Band1 As Petrol_Band1, Band2 As Petrol_Band2, Band3 As Petrol_Band3, ModifiedDate, OrganisationID 
    FROM [FuelRates_Petrol]
    WHERE OrganisationID = @OrganisationID

【讨论】:

谢谢Shaneis。我的代码现在看起来像这样:pastebin.com/kGM7kSQa 生成 3 行而不是我想要的那一行。有什么办法可以将它组合成一行? J Greene 的回答是我打算采用的。唯一需要注意的是,我会确保紧跟在 FROM 之后的表有 OrganizationID 的记录,否则即使其他表有记录,也不会返回任何内容。【参考方案2】:

你可以试试这个...

ALTER PROCEDURE [dbo].[FuelRates_RetrieveList] 
    @OrganisationID int
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    CREATE TABLE #FuelRates(
    OrganisationID int,
    Petrol_Band1 int, 
    Petrol_Band2 int,
    Petrol_Band3 int,
    LPG_Band1 int,
    LPG_Band2 int,
    LPG_Band3 int,
    Diesel_Band1 int,
    Diesel_Band2 int,
    Diesel_Band3 int,
    ModifiedDate DateTime)

    INSERT INTO #FuelRates
    (OrganisationID, Petrol_Band1, Petrol_Band2, Petrol_Band3,LPG_Band1,LPG_Band2,LPG_Band3,
      Diesel_Band1, Diesel_Band2, Diesel_Band3, ModifiedDate)
    SELECT OrganisationID,
        p.Band1 As Petrol_Band1, p.Band2 As Petrol_Band2, p,Band3 As Petrol_Band3, 
        lp.Band1 As LPG_Band1, lp.Band2 As LPG_Band2, lp.Band3 As LPG_Band3,
        d.Band1 As Diesel_Band1, d.Band2 As Diesel_Band2, d.Band3 As Diesel_Band3,
        GetDate() as ModifiedDate
    FROM [FuelRates_Petrol] p
    LEFT JOIN FuelRates_LPG lp on lp.OrganisationID = p.OrganisationID
    LEFT JOIN FuelRates_Diesel d on d.OrganizationID = p.OrganisationID
    WHERE p.OrganisationID = @OrganisationID

    SELECT * FROM #FuelRates

    DROP TABLE #FuelRates
END

【讨论】:

这就是我如此喜欢的原因!谢谢。这是一种享受。虽然您在 SELECT 中有语法错误(p,Band3 As Petrol_Band3 - 逗号而不是句点)

以上是关于从多个表中选择并组合成单行临时表的主要内容,如果未能解决你的问题,请参考以下文章

将数据从表插入临时表,然后从临时表中选择特定行

雪花我们如何遍历临时表的每一行并将其值插入到另一个表中,其中每个字段的值都是单行?

MySQL INSERT ... 从 1 个表中选择 2 个表

无法从 plpgsql 函数中的动态命名临时表运行“选择进入”

MYSQL 从存储过程中的临时表中选择 JOIN 不起作用

SQL存储过程多个结果到临时表中