Подтвердить что ты не робот

Как установить строку по умолчанию для запроса, который не возвращает строк?

Мне нужно знать, как вернуть строку по умолчанию, если в таблице нет строк. Какой был бы лучший способ сделать это? Я возвращаю только один столбец из этой таблицы, чтобы получить его значение.

Изменить: это будет SQL Server.

4b9b3361

Ответ 1

В Oracle:

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

Или, альтернативно:

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

Ответ 2

Если ваш базовый запрос должен возвращать только одну строку, вы можете использовать этот трюк:

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

(код Oracle, не уверен, что NVL - это правильная функция для SQL Server.)

Ответ 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

Как насчет этого:

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

Один метод сканирования таблицы с использованием левого соединения от значений по умолчанию:

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

Ответ 6

Вы хотите вернуть полную строку? Должна ли строка по умолчанию иметь значения по умолчанию или может быть пустой строкой? Вы хотите, чтобы строка по умолчанию имела ту же структуру столбцов, что и таблица?

В зависимости от ваших требований вы можете сделать что-то вроде этого:

1) запустите запрос и поместите результаты в таблицу temp (или переменную таблицы) 2) проверьте, имеет ли таблица temp результаты 3) если нет, верните пустую строку, выполнив оператор select, подобный этому (в SQL Server):

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

Если columnA, columnB и columnC являются вашими фактическими именами столбцов.

Ответ 7

Я понял это, и он также должен работать и для других систем. Это вариация ответа 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 )

Ответ 8

Вставьте значения по умолчанию в переменную таблицы, а затем обновите эту таблицу в одной строке с совпадением с вашей фактической таблицей. Если строка найдена, будет обновлен 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