假设我有一个带有此架构的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)第二个表显示了预期的结果。
答案 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