SQL SELECT具有默认值

时间:2011-03-15 09:44:57

标签: sql

假设我有一个带有此架构的SQL表:

CREATE TABLE(
foo INTEGER,
bar INTEGER,
baz INTEGER DEFAULT 0
);

包含数据

foo|bar|baz
-----------
1  |1  |2
2  |3  |4

我对foo的值1,2和bar的1,2,3感兴趣。是否有SQL请求会返回“缺失”值以及现有值:

foo|bar|baz
-----------
1  |1  |2
1  |2  |0
1  |3  |0
2  |1  |0
2  |2  |0
2  |3  |4

?我怀疑没有,但也许我只是不知道呢?

更新: 1)使用SQLite 3; 2)缺失值由DEFAULT子句给出; 3)第二个表显示了预期的结果。

4 个答案:

答案 0 :(得分:4)

假设您为表格Data命名,以下内容可以为您提供已发布的结果。

  • WITH语句创建一个临时的内存表,其中包含实际表中从1到最大值的所有Bar。
  • CROSS APPLY会为您的表格中存在的每个条形都返回一行。
  • CASE语句选择现有的baz(如果存在),否则选择0。

SQL声明

WITH q AS (
  SELECT  [bar] = 1
          , [MaxBar] = MAX(bar)
  FROM    Data
  UNION ALL 
  SELECT  q.bar + 1
          , q.MaxBar
  FROM    q
  WHERE   q.bar + 1 <= q.MaxBar
)  
SELECT  Data.foo
        , q.bar
        , CASE WHEN q.bar = Data.bar THEN Data.baz ELSE 0 END
FROM    q
        CROSS APPLY Data
ORDER BY
        Data.foo
        , q.bar

测试脚本

WITH Data AS (
  SELECT [foo] = 1, [bar] = 1, [baz] = 2
  UNION ALL SELECT 2, 3, 4
), q AS (
  SELECT  [bar] = MIN(bar)
          , [MaxBar] = MAX(bar)
  FROM    Data
  UNION ALL 
  SELECT  q.bar + 1
          , q.MaxBar
  FROM    q
  WHERE   q.bar + 1 <= q.MaxBar
)  
SELECT  Data.foo
        , q.bar
        , CASE WHEN q.bar = Data.bar THEN Data.baz ELSE 0 END
FROM    q
        CROSS APPLY Data
ORDER BY
        Data.foo
        , q.bar

答案 1 :(得分:2)

创建以下表格

table_foo

foo|
-----------
1  |
2  |

table_bar

bar|
-----------
1  |
2  |
3  |

之后,此查询应该可以解决问题:

select * from  table
UNION
(
    select 
        table_foo.foo,
        table_bar.bar,
        0 
    from
        table,
        table_foo, 
        table_bar
    where 
        table.foo != table_foo.foo and
        table.bar != table_bar.bar
)

答案 2 :(得分:1)

假设您的表名为MyTab,这个sql将生成第二个数据表(我假设是MSSQL):

select 
    f.foo,
    b.bar,
    baz = coalesce(m.baz,0)
from 
    (select foo = 1 union select foo = 2) f
    cross join (select bar = 1 union select bar = 2 union select bar = 3) b
    left join mytab m on f.foo = m.foo and b.bar = m.bar

答案 3 :(得分:1)

declare @foovalues table (foo int) -- values 1,2 for foo
insert into @foovalues values (1) 
insert into @foovalues values (2)

declare @barvalues table (bar int) -- values 1,2,3 for bar
insert into @barvalues values (1) 
insert into @barvalues values (2)
insert into @barvalues values (3)

declare @table table (foo int, bar int, baz int) -- your data
insert into @table values (1,1,2)
insert into @table values (2,3,4)

select x.foo, x.bar, isnull(baz, 0) as baz
from (select f.foo, b.bar from @foovalues f, @barvalues b) as x
left outer join @table t on t.foo = x.foo and t.bar = x.bar
order by x.foo, x.bar