it-swarm.com.de

Wie kann eine Standardzeile für eine Abfrage festgelegt werden, die keine Zeilen zurückgibt?

Ich muss wissen, wie eine Standardzeile zurückgegeben wird, wenn in einer Tabelle keine Zeilen vorhanden sind. Was wäre der beste Weg, dies zu tun? Ich gebe nur eine einzelne Spalte aus dieser bestimmten Tabelle zurück, um deren Wert zu erhalten. 

Edit: Das wäre SQL Server. 

27
John Baughman

Ein Ansatz für Oracle:

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

Oder alternativ in Oracle:

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

Oder alternativ in SqlServer:

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

Diese verwenden die Tatsache, dass MIN()NULL zurückgibt, wenn keine Zeilen vorhanden sind.

29
WW.

Wenn erwartet wird, dass Ihre Basisabfrage nur eine Zeile zurückgibt, können Sie diesen Trick verwenden:

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

(Oracle-Code, nicht sicher, ob NVL die richtige Funktion für SQL Server ist.)

13
Dave Costa

Dadurch würde die Auswahlabfrage nicht zweimal ausgeführt und die Leistung ist besser:

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'
10
duckworth

Wie wäre es damit:

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

Ergebnisse

Gültige Rate existiert

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

Default Rate Used

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

DDL testen

CREATE TABLE d_payment_index (rate int NOT NULL)
INSERT INTO d_payment_index VALUES (1)
6
beach

Ich habe es herausgefunden, und es sollte auch für andere Systeme funktionieren. Es ist eine Variation der Antwort von 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 )
2
John Baughman

Eine Tabellenscanmethode, die eine linke Verknüpfung verwendet, von den Standardwerten bis zu den tatsächlichen Werten:

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]

Gibt Ausgabe aus:

k           Value
----------- ------------
0           DefaultValue

k           Value
----------- ------------
1           1-1
1           1-2
1           1-3

k           Value
----------- ------------
2           2-1
2           2-2
2
Cade Roux

Möchten Sie eine vollständige Reihe zurückgeben? Muss die Standardzeile Standardwerte haben oder kann es sich um eine leere Zeile handeln? Soll die Standardzeile dieselbe Spaltenstruktur haben wie die betreffende Tabelle?

Abhängig von Ihren Anforderungen können Sie Folgendes tun:

1) Führen Sie die Abfrage aus, und geben Sie die Ergebnisse in eine temporäre Tabelle (oder Tabellenvariable) 2) Prüfen Sie, ob die temporäre Tabelle Ergebnisse enthält 3. Wenn nicht, geben Sie eine leere Zeile zurück, indem Sie eine select-Anweisung ausführen, die der ähnelt Dies (in SQL Server):

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

Dabei sind Spalte A, Spalte B und Spalte C die tatsächlichen Spaltennamen.

1
Jason Anderson

Fügen Sie Ihre Standardwerte in eine Tabellenvariable ein und aktualisieren Sie dann die einzelne Zeile dieser tableVar mit einer Übereinstimmung von Ihrer tatsächlichen Tabelle. Wenn eine Zeile gefunden wird, wird tableVar aktualisiert. Andernfalls bleibt der Standardwert erhalten. Liefert die Tabellenvariable.

    ---=== 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)

Hier ist die Lösung:

---=== 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

Testen Sie den Code:

EXEC dbo.GetRate @PkId=1     --- returns values for PkId=1
EXEC dbo.GetRate @PkId=12314 --- returns default values
0
Y-Mi Wong

Dieses Snippet verwendet Common Table-Ausdrücke, um redundanten Code zu reduzieren und die Lesbarkeit zu verbessern. Es ist eine Variation von John Baughmans Antwort. 

Die Syntax gilt für SQL Server. 

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 );
0
Eike