簡體   English   中英

SQL Server 2008 R2即使沒有結果也返回一行

[英]SQL Server 2008 R2 return a row even when no results

我有一個包含以下一些數據的表:

+------+--------+-----+------+
| Team | Status | Bye | Wins |
+------+--------+-----+------+
| Cle  | New    |   1 |    5 |
| Tam  | New    |   3 |    0 |
| Bal  | New    |   3 |    2 |
| Ind  | Cur    |   4 |    0 |
| LAC  | New    |   4 |    2 |
| NYG  | Cur    |   5 |    0 |
| Chi  | Cur    |   5 |    0 |
+------+--------+-----+------+

有5個再見周,在這種情況下,查詢可能會返回沒有特定再見周的結果,例如2個。 我想從表中返回一個記錄集,但還要返回一行,在“再見”周中缺少數字,而該行中的其他所有內容都為空(其中沒有“再見”)。 我想我可以使用UNION做到這一點,但似乎需要做很多工作,並希望有一種更簡單,更有效的方法。

我看過其他帖子返回一個空行,但其中不包括返回其他有效行。 謝謝你的幫助。

您可以將values構造與join

select t.bye, tt.*
from ( values (2) 
     ) t (bye) left join
     table tt
     on t.bye = tt.bye;

編輯:再次審查問題后,您似乎希望與not exists union

select t.team, t.status, t.bye, t.wins
from table t
where bye = 2
union all
select t.team, t.status, t.bye, t.wins
from table t
where not exists (select 1 from table where bye = 2);

編輯:使用遞歸cte查找丟失的bye

with t as (
     select min(bye) mn_bye, max(bye) mx_bye
     from table
     union all
     select mn_bye + 1, mx_bye
     from t
     where mn_bye < mx_bye
)

select tt.*, coalesce(cast(t.mn_bye as varchar(255)), 'missing') 
from t left join
     table tt
     on tt.bye = t.mn_bye;

這里還有其他一些很好的答案,但是我將分享在類似情況下所做的事情。 基本上,我有一個“默認值”表,可以將其UNION合並到該表中,然后僅返回該表中所有缺少的行。

基於上面的示例數據,我創建了以下示例,您可以在SSMS中運行它。

-- replicate your environment --

DECLARE @data TABLE ( [team] VARCHAR(3), [status] VARCHAR(3), [bye] INT, [wins] INT );
INSERT INTO @data ( [team], [status], [bye], [wins] )
VALUES
  ( 'Cle', 'New', 1, 5 )
, ( 'Tam', 'New', 3, 0 )
, ( 'Bal', 'New', 3, 2 )
, ( 'Ind', 'Cur', 4, 0 )
, ( 'LAC', 'New', 4, 2 )
, ( 'NYG', 'Cur', 5, 0 )
, ( 'Chi', 'Cur', 5, 0 );

-- declare a "defaults" table variable --

DECLARE @defaults TABLE ( [team] VARCHAR(2) DEFAULT '--', [status] VARCHAR(2) DEFAULT '--', [bye] INT, [wins] INT );

-- insert default data based on what I surmised from your question --

INSERT INTO @defaults ( [bye], [wins] ) VALUES ( 1, 0 ), ( 2, 0 ), ( 3, 0 ), ( 4, 0 ), ( 5, 0 );

-- select data using the "defaults" table to "fill in the wholes" --

SELECT [team], [status], [bye], [wins] FROM @data
UNION
SELECT [team], [status], [bye], [wins] FROM @defaults
WHERE [bye] NOT IN ( SELECT [bye] FROM @data )
ORDER BY
    [bye], [team];

哪個返回

+------+--------+-----+------+
| team | status | bye | wins |
+------+--------+-----+------+
| Cle  | New    |   1 |    5 |
| --   | --     |   2 |    0 |
| Bal  | New    |   3 |    2 |
| Tam  | New    |   3 |    0 |
| Ind  | Cur    |   4 |    0 |
| LAC  | New    |   4 |    2 |
| Chi  | Cur    |   5 |    0 |
| NYG  | Cur    |   5 |    0 |
+------+--------+-----+------+

另一種選擇是擴展@Yogesh對FROM ( VALUES )的使用:

SELECT [team], [status], [bye], [wins] FROM @data
UNION
SELECT [team], [status], [bye], [wins] 
FROM ( 
    VALUES ( '--', '--', 1, 0 ), ( '--', '--', 2, 0 ), ( '--', '--', 3, 0 ), ( '--', '--', 4, 0 ), ( '--', '--', 5, 0 )
 ) AS MyTable( [team], [status], [bye], [wins] )
WHERE [bye] NOT IN ( SELECT [bye] FROM @data )
ORDER BY
    [bye], [team];

它返回與上面相同的結果,而無需/開銷表變量。

我故意刪除了帶有4的Bye ,以便可以更好地看到結果。

declare @t table
(
    Team     char(3) null,
    [Status] char(3) null,
    Bye      tinyint null,
    Wins     tinyint null
);

insert into @t values
('Cle', 'New', 1, 5),
('Tam', 'New', 3, 0),
('Bal', 'New', 3, 2),
--('Ind', 'Cur', 4, 0),
--('LAC', 'New', 4, 2),
('NYG', 'Cur', 5, 0),
('Chi', 'Cur', 5, 0);

with info as
(
    select x.*, x.next_row_bye - Bye diff
    from
    (
        select *,
               LEAD(Bye) OVER (ORDER BY Bye) next_row_bye,
               Bye + 1 next_bye
        from @t
    ) x
)
select null Team, null [Status], next_bye Bye, 0 Wins
from info
where diff > 0
union
select *
from @t
order by Bye;

結果:

IMG1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM