【问题标题】:Efficiently SELECT either a real record or a virtual/default "record" in .NET/T-SQL在 .NET/T-SQL 中有效地选择真实记录或虚拟/默认“记录”
【发布时间】:2020-03-11 02:37:45
【问题描述】:

我有一个结构可以处理来自单个查询的已加载 .NET 数据集的数据。我有一个表旨在覆盖我的应用程序驱动的默认值。演示如何构建设置覆盖表:

CREATE TABLE TABLE1(
    PK int IDENTITY(1,1) NOT NULL,
    VALINT int NOT NULL,
    DESCRIPTION1 varchar(50) NOT NULL
)

我的代码将生成带有内置默认值的 SQL,并与表中的自定义覆盖数据并入查询并返回单个数据集:

SELECT C.VALINT, C.DESCRIPTION1
    FROM (
        SELECT MAX(PK)AS PK, VALINT
        FROM (
            SELECT PK, VALINT
            FROM TABLE1
            UNION
            SELECT 0, 1
            UNION
            SELECT 0, 2
        ) A
        GROUP BY VALINT
    )B, (
        SELECT PK, VALINT, DESCRIPTION1
        FROM TABLE1
        UNION
        SELECT 0, 1, 'Default1Val'
        UNION
        SELECT 0, 2, 'Default2Val'
    ) C
    WHERE B.PK = C.PK AND B.VALINT = C.VALINT

对空表运行此查询,您将只看到查询中定义的两个默认设置。然后可以添加一个新的自定义覆盖:

INSERT INTO TABLE1(VALINT,DESCRIPTION1)VALUES(1,'CustomOverride1')

现在重新运行上述查询,您将看到表中的一个自定义值和一个剩余的未覆盖的默认值。此查询完全符合我的需要,但是当以这种方式完成时,表中的数据将与默认设置数据联合两次不同的时间。是否可以使用一组 UNION 进行更优雅的查询,或者我是否坚持使用两套完整的 UNION,如上所示?

【问题讨论】:

  • 我认为如果你正确使用ISNULLLEFT OUTER JOIN的组合,你应该能够实现你的目标。

标签: .net sql-server tsql


【解决方案1】:

这是公用表表达式 (CTE) 非常有用的地方。

我还更正了您的连接 - 不建议使用逗号分隔连接(旧式连接),而是使用显式连接类型。

declare @TABLE1 table (
    PK int IDENTITY(1,1) NOT NULL,
    VALINT int NOT NULL,
    DESCRIPTION1 varchar(50) NOT NULL
);

WITH cte AS (
    SELECT PK, VALINT, DESCRIPTION1
    FROM @TABLE1
    UNION
    SELECT 0, 1, 'Default1Val'
    UNION
    SELECT 0, 2, 'Default2Val'
)
SELECT C.VALINT, C.DESCRIPTION1
FROM (
    SELECT MAX(PK)AS PK, VALINT
    FROM cte A
    GROUP BY VALINT
) B
inner join cte C on B.PK = C.PK AND B.VALINT = C.VALINT;

返回:

VALINT  DESCRIPTION1
1       Default1Val
2       Default2Val

添加自定义覆盖给出:

INSERT INTO @TABLE1 (VALINT,DESCRIPTION1) VALUES(1,'CustomOverride1');

WITH cte AS (
    SELECT PK, VALINT, DESCRIPTION1
    FROM @TABLE1
    UNION
    SELECT 0, 1, 'Default1Val'
    UNION
    SELECT 0, 2, 'Default2Val'
)
SELECT C.VALINT, C.DESCRIPTION1
FROM (
    SELECT MAX(PK)AS PK, VALINT
    FROM cte A
    GROUP BY VALINT
) B
inner join cte C on B.PK = C.PK AND B.VALINT = C.VALINT;

返回:

VALINT  DESCRIPTION1
2       Default2Val
1       CustomOverride1

【讨论】:

    【解决方案2】:

    你必须选择你需要用来解决你的任务。 join用于合并不同表的列,union用于合并行

    当你合并两个表时,它们有几个要求

    1. 两个选择语句的列数必须相同
    2. 按顺序排列的列必须是相同的数据类型

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 2023-03-25
      相关资源
      最近更新 更多