복붙노트

[SQL] 어떻게 어떤 행을 반환하지 않는 쿼리에 대한 기본 행을 설정하는 방법?

SQL

어떻게 어떤 행을 반환하지 않는 쿼리에 대한 기본 행을 설정하는 방법?

나는 행이 테이블에 존재하지 않는 경우 기본 행을 반환하는 방법을 알아야합니다. 이 작업을 수행하는 가장 좋은 방법이 있을까요? 난 단지 그 값을 얻기 위해이 특정 테이블에서 하나의 열을 반환하고 있습니다.

편집 : 이것은 SQL 서버가 될 것입니다.

해결법

  1. ==============================

    1.하나는 오라클에 대한 접근 :

    하나는 오라클에 대한 접근 :

    SELECT val
    FROM myTable
    UNION ALL
    SELECT 'DEFAULT'
    FROM dual
    WHERE NOT EXISTS (SELECT * FROM myTable)
    

    또는 대안 오라클 :

    SELECT NVL(MIN(val), 'DEFAULT')
    FROM myTable
    

    또는 대안 SQLSERVER에서 :

    SELECT ISNULL(MIN(val), 'DEFAULT')
    FROM myTable
    

    이 사용하는 행이없는 경우 MIN () 반환 NULL 사실.

  2. ==============================

    2.베이스 쿼리가 하나 개의 행을 리턴 할 것으로 예상되는 경우,이 트릭을 사용할 수 있습니다 :

    베이스 쿼리가 하나 개의 행을 리턴 할 것으로 예상되는 경우,이 트릭을 사용할 수 있습니다 :

    select NVL( MIN(rate), 0 ) AS rate 
    from d_payment_index
    where fy = 2007
      and payment_year = 2008
      and program_id = 18
    

    (오라클 코드는 NVL는 SQL Server의 올바른 기능은 확실하지합니다.)

  3. ==============================

    3.이 두 번 실행 선택 쿼리를 제거하고 성능을 위해 더 좋을 것입니다 :

    이 두 번 실행 선택 쿼리를 제거하고 성능을 위해 더 좋을 것입니다 :

    Declare @rate int
    
    select 
        @rate = rate 
    from 
        d_payment_index
    where 
        fy = 2007
        and payment_year = 2008
        and program_id = 18
    
    IF @@rowcount = 0
        Set @rate = 0
    
    Select @rate 'rate'
    
  4. ==============================

    4.이건 어때요:

    이건 어때요:

    SELECT DEF.Rate, ACTUAL.Rate, COALESCE(ACTUAL.Rate, DEF.Rate) AS UseThisRate
    FROM 
      (SELECT 0) DEF (Rate) -- This is your default rate
    LEFT JOIN (
      select rate 
      from d_payment_index
      --WHERE 1=2   -- Uncomment this line to simulate a missing value
    
      --...HERE IF YOUR ACTUAL WHERE CLAUSE. Removed for testing purposes...
      --where fy = 2007
      -- and payment_year = 2008
      --  and program_id = 18
    ) ACTUAL (Rate) ON 1=1
    

    결과

    유효 비율은 존재

    Rate        Rate        UseThisRate
    ----------- ----------- -----------
    0           1           1
    

    속도는 사용하는 기본

    Rate        Rate        UseThisRate
    ----------- ----------- -----------
    0           NULL        0
    

    테스트 DDL

    CREATE TABLE d_payment_index (rate int NOT NULL)
    INSERT INTO d_payment_index VALUES (1)
    
  5. ==============================

    5.나는 그것을 파악, 또한 너무 다른 시스템에 작동합니다. 그것은 WW의 대답의 변형입니다.

    나는 그것을 파악, 또한 너무 다른 시스템에 작동합니다. 그것은 WW의 대답의 변형입니다.

    select rate 
    from d_payment_index
    where fy = 2007
      and payment_year = 2008
      and program_id = 18
    union
    select 0 as rate 
    from d_payment_index 
    where not exists( select rate 
                      from d_payment_index
                      where fy = 2007
                        and payment_year = 2008
                        and program_id = 18 )
    
  6. ==============================

    6.왼쪽을 사용하여 하나 개의 테이블 스캔 방법은 기본값과 실제에 가입 :

    왼쪽을 사용하여 하나 개의 테이블 스캔 방법은 기본값과 실제에 가입 :

    CREATE TABLE [stackoverflow-285666] (k int, val varchar(255))
    
    INSERT  INTO [stackoverflow-285666]
    VALUES  (1, '1-1')
    INSERT  INTO [stackoverflow-285666]
    VALUES  (1, '1-2')
    INSERT  INTO [stackoverflow-285666]
    VALUES  (1, '1-3')
    INSERT  INTO [stackoverflow-285666]
    VALUES  (2, '2-1')
    INSERT  INTO [stackoverflow-285666]
    VALUES  (2, '2-2')
    
    DECLARE @k AS int
    SET @k = 0
    
    WHILE @k < 3
        BEGIN
            SELECT  @k AS k
                   ,COALESCE(ActualValue, DefaultValue) AS [Value]
            FROM    (
                     SELECT 'DefaultValue' AS DefaultValue
                    ) AS Defaults
            LEFT JOIN (
                       SELECT   val AS ActualValue
                       FROM     [stackoverflow-285666]
                       WHERE    k = @k
                      ) AS [Values]
                    ON 1 = 1
    
            SET @k = @k + 1
        END
    
    DROP TABLE [stackoverflow-285666]
    

    출력을 제공합니다 :

    k           Value
    ----------- ------------
    0           DefaultValue
    
    k           Value
    ----------- ------------
    1           1-1
    1           1-2
    1           1-3
    
    k           Value
    ----------- ------------
    2           2-1
    2           2-2
    
  7. ==============================

    7.이 조각은 중복 코드를 줄이고 가독성을 향상시키기 위해 공통 테이블 식을 사용합니다. 요한 Baughman은의 대답의 변형입니다.

    이 조각은 중복 코드를 줄이고 가독성을 향상시키기 위해 공통 테이블 식을 사용합니다. 요한 Baughman은의 대답의 변형입니다.

    구문은 SQL 서버를위한 것입니다.

    WITH products AS (
                SELECT prod_name,
                       price
                  FROM Products_Table
                 WHERE prod_name LIKE '%foo%'
         ),
         defaults AS (
                SELECT '-' AS prod_name,
                       0   AS price
         )
    
    SELECT * FROM products
    UNION ALL
    SELECT * FROM defaults
     WHERE NOT EXISTS ( SELECT * FROM products );
    
  8. ==============================

    8.당신은 전체 행을 반환 하시겠습니까? 기본 행 필요 기본값이 있어야합니다 않거나 빈 행이 될 수 있습니까? 당신은 기본 행 문제의 테이블과 같은 열 구조를 가지고 하시겠습니까?

    당신은 전체 행을 반환 하시겠습니까? 기본 행 필요 기본값이 있어야합니다 않거나 빈 행이 될 수 있습니까? 당신은 기본 행 문제의 테이블과 같은 열 구조를 가지고 하시겠습니까?

    요구 사항에 따라, 당신은 이런 식으로 뭔가를 할 수 있습니다

    1)) 쿼리를 실행하고 임시 테이블에서 결과 (또는 테이블 변수를 넣어 2) 임시 테이블 결과가 있는지 확인 3)하지 않을 경우 다음과 유사한 SELECT 문을 (SQL 서버)에서 수행하여 빈 행을 반환합니다 :

    select '' as columnA, '' as columnB, '' as columnC from #tempTable
    

    열, 열 및 열 실제 열 이름입니다 경우.

  9. ==============================

    9.다음 실제 테이블의 일치로이 tableVar의 단일 행을 업데이트 테이블 변수에 기본 값을 삽입합니다. 행이있는 경우, tableVar가 업데이트됩니다; 하지 않을 경우, 기본값은 남아있다. 테이블 변수를 돌려줍니다.

    다음 실제 테이블의 일치로이 tableVar의 단일 행을 업데이트 테이블 변수에 기본 값을 삽입합니다. 행이있는 경우, tableVar가 업데이트됩니다; 하지 않을 경우, 기본값은 남아있다. 테이블 변수를 돌려줍니다.

        ---=== The table & its data
        CREATE TABLE dbo.Rates (
            PkId int,
            name varchar(10),
            rate decimal(10,2)
        )
        INSERT INTO dbo.Rates(PkId, name, rate) VALUES (1, 'Schedule 1', 0.1)
        INSERT INTO dbo.Rates(PkId, name, rate) VALUES (2, 'Schedule 2', 0.2)
    

    여기에 솔루션입니다 :

    ---=== The solution 
    CREATE PROCEDURE dbo.GetRate 
      @PkId int
    AS
    BEGIN
      DECLARE @tempTable TABLE (
        PkId int, 
        name varchar(10), 
        rate decimal(10,2)
     )
    
     --- [1] Insert default values into @tempTable. PkId=0 is dummy value  
     INSERT INTO @tempTable(PkId, name, rate) VALUES (0, 'DEFAULT', 0.00)
    
     --- [2] Update the single row in @tempTable with the actual value.
     ---     This only happens if a match is found
     UPDATE @tempTable
        SET t.PkId=x.PkId, t.name=x.name, t.rate = x.rate
        FROM @tempTable t INNER JOIN dbo.Rates x
        ON t.PkId = 0
        WHERE x.PkId = @PkId
    
     SELECT * FROM @tempTable
    END
    

    코드를 테스트 :

    EXEC dbo.GetRate @PkId=1     --- returns values for PkId=1
    EXEC dbo.GetRate @PkId=12314 --- returns default values
    
  10. from https://stackoverflow.com/questions/285666/how-to-set-a-default-row-for-a-query-that-returns-no-rows by cc-by-sa and MIT license