如果配置存在则选择第一行,否则选择 NULL Row

Posted

技术标签:

【中文标题】如果配置存在则选择第一行,否则选择 NULL Row【英文标题】:Select first Row if configuration exists, otherwise select NULL Row 【发布时间】:2016-11-04 07:25:09 【问题描述】:

给定一个 SQL Server 2008 实例,假设有一个名为 @Configuration 的表,它包含三列:IDCodeSubCodeCodeSubCode 不应有重复的行。

现在想象另一个详细级别表@ConfigurationDetails,其中有Code 的重复行,并且SubCode 的子代码可能为空。

如果SubCode 可用,则直接从详细信息表中选择AmtData,如果SubCode 在详细信息表中不可用,则在NULL 记录中选择AmtData /p>

(注意:SubCode=NULL 条目始终可用于每个配置行)

关于从哪里开始有什么想法吗?

例如 一个简单的例子... 表

declare @Configuration TABLE ( 
      ID INTEGER IDENTITY PRIMARY KEY,
      Code VARCHAR(50),
      SubCode VARCHAR(50)


);

declare @ConfigurationDetails TABLE 
( 
    Code VARCHAR(50),
    SubCode VARCHAR(50),
    Amt MONEY,
    Data VARCHAR(123)
);


INSERT INTO @Configuration VALUES
('BR1','Sub1'),
('BR1','Sub2'),
('BR1','Sub3'),
('BR1','Sub4'),
('BR2','Sub1'),
('BR2','Sub2')

INSERT INTO @ConfigurationDetails VALUES
('BR1','Sub1',500,'BR1 Sub1 Data'),
('BR1','Sub2',600,'BR1 Sub2 Data'),
('BR1',NULL,700,'BR1 Data'),
('BR2','Sub1',500,'BR2 Sub1 Data'),
('BR2',NULL,700,'BR2 Data')


INPUT:
@SubCode  = 'Sub1', @Code = 'BR1'

OUTPUT:
Code    SubCode Amt Data
====    ======= === ====
BR1     Sub1    500 BR1 Sub1 Data

INPUT:
@SubCode  = 'Sub4', @Code = 'BR1'

OUTPUT:
Code    SubCode Amt Data
====    ======= === ====
BR1     NULL    700 BR1 Data

【问题讨论】:

首先你的例子有错误,你不能向标识列插入值(除非使用 Insert_identity on ),所以处理你的例子然后重新访问。 这听起来很像学校作业。您是否尝试过自己解决这个问题?如果有,你的代码在哪里? 【参考方案1】:

你应该可以使用类似的东西

SELECT *
FROM   @Configuration c
       CROSS APPLY (SELECT TOP 1 *
                    FROM   @ConfigurationDetails cd
                    WHERE  c.Code = cd.Code
                           AND ( c.SubCode = cd.SubCode
                                  OR c.SubCode IS NULL )
                    ORDER  BY cd.SubCode DESC --Order the not null match first if it exists
                   ) CA 

【讨论】:

【参考方案2】:
WITH cte
AS (
        SELECT  a.ID, 
                a.Code, 
                a.SubCode, 
                b.SubCode as bSubCode, 
                b.Amt, 
                b.Data,
                ROW_NUMBER() OVER(PARTITION BY a.CODE, a.SubCode ORDER BY B.SUBCODE desc) as RN
          FROM  @Configuration as a
          LEFT  JOIN @ConfigurationDetails as b ON b.Code = a.Code
                AND (a.SubCode = b.SubCode OR b.SubCode IS NULL)
        )
        SELECT * FROM cte
        where rn=1

【讨论】:

以上是关于如果配置存在则选择第一行,否则选择 NULL Row的主要内容,如果未能解决你的问题,请参考以下文章

如果不存在子集,则选择全部,否则选择子集

如果选择了 GridViewRow 则...否则

如果存在则从表中选择,否则从oracle中的另一个表中选择

如果值不存在,则选择空行

如何参数化 Postgres-custom-function 中的表和列,如果值存在则选择 PK,否则插入并返回 PK?

如果可用,则选择第二行(如果不是第一行)