Sql server 在SQL查询输出中包括0或空的行
我通过两个不同查询的联合查询不同项目类型的数据(多列)。如果某个特定项目类型的任何列中都没有值,则不会显示该记录。但是,我需要与每个项目类型相关的所有行(包括空行)。空行可以显示0 我的数据是:Sql server 在SQL查询输出中包括0或空的行,sql-server,Sql Server,我通过两个不同查询的联合查询不同项目类型的数据(多列)。如果某个特定项目类型的任何列中都没有值,则不会显示该记录。但是,我需要与每个项目类型相关的所有行(包括空行)。空行可以显示0 我的数据是: create table sales_table ([yr] int, [qtr] varchar(40), [item_type] varchar(40), [sale_price] int); create table profit_table ([yr] int, [qtr] varchar(40
create table sales_table ([yr] int, [qtr] varchar(40), [item_type] varchar(40), [sale_price] int);
create table profit_table ([yr] int, [qtr] varchar(40), [item_type] varchar(40), [profit] int);
create table item_table ([item_type] varchar(40));
insert into sales_table values
(2010,'Q1','abc',31),(2010,'Q1','def',23),(2010,'Q1','mno',12),(2010,'Q1','xyz',7),(2010,'Q2','abc',54),(2010,'Q2','def',67),(2010,'Q2','mno',92),(2010,'Q2','xyz',8);
insert into profit_table values
(2010,'Q1','abc',10),(2010,'Q1','def',6),(2010,'Q1','mno',23),(2010,'Q1','xyz',7),(2010,'Q2','abc',21),(2010,'Q2','def',13),(2010,'Q2','mno',15),(2010,'Q2','xyz',2);
insert into item_table values
('abc'),('def'),('ghi'),('jkl'),('mno'),('xyz');
我的问题是:
SELECT a.yr, a.qtr, b.item_type, MAX(a.sales), MAX(a.avg_price), MAX(a.profit)
FROM
(SELECT [yr], [qtr],
CASE WHEN item_type IN ('mno', 'xyz') THEN 'Other' else upper(item_type) END AS [item_type],
COUNT(sale_price) OVER (PARTITION BY yr, qtr, item_type) [sales],
AVG(sale_price) OVER (PARTITION BY yr, qtr, item_type) [avg_price],
NULL [profit]
FROM sales_table
WHERE yr >=2010
UNION ALL
SELECT yr, qtr,
CASE WHEN item_type IN ('mno', 'xyz') THEN 'Other' else upper(item_type) END AS [item_type],
NULL [sales],
NULL [avg_price],
SUM(profit) OVER (PARTITION BY yr, qtr, item_type) [profit]
FROM profit_table
WHERE yr >=2010
) a
FULL OUTER JOIN
(SELECT
CASE WHEN item_type IN ('mno', 'xyz') THEN 'Other' else upper(item_type) END AS [item_type]
FROM item_table
WHERE item_type in ('abc','def','ghi','jkl','mno','xyz')
) b
ON a.item_type = b.item_type
GROUP BY a.yr, a.qtr, b.item_type
ORDER BY a.yr, a.qtr, b.item_type;
电流输出如下所示:
yr qtr item_type sales avg_price profit
(null) (null) GHI (null) (null) (null)
(null) (null) JKL (null) (null) (null)
2010 Q1 ABC 1 31 10
2010 Q1 DEF 1 23 6
2010 Q1 Other 1 12 23
2010 Q2 ABC 1 54 21
2010 Q2 DEF 1 67 13
2010 Q2 Other 1 92 15
我想要的是如下所示
yr qtr item_type sales avg_price profit
2010 Q1 ABC 1 31 10
2010 Q1 DEF 1 23 6
2010 Q1 GHI 0 0 0
2010 Q1 JKL 0 0 0
2010 Q1 Other 2 9.5 30
2010 Q2 ABC 1 54 21
2010 Q2 DEF 1 67 13
2010 Q2 GHI 0 0 0
2010 Q2 JKL 0 0 0
2010 Q2 Other 2 50 17
请告知。给你。就像评论中描述的那样 我做了一个迷你日历桌,但你会想花些时间做一个真正的。一旦你拥有了它,你就会一直使用它
if OBJECT_ID('tempdb..#sales_table', 'U') is not null
drop table #sales_table
if OBJECT_ID('tempdb..#profit_table', 'U') is not null
drop table #profit_table
if OBJECT_ID('tempdb..#item_table', 'U') is not null
drop table #item_table
if OBJECT_ID('tempdb..#date_table', 'U') is not null
drop table #date_table
create table #sales_table
(
[yr] int
, [qtr] varchar(40)
, [item_type] varchar(40)
, [sale_price] int
);
create table #profit_table
(
[yr] int
, [qtr] varchar(40)
, [item_type] varchar(40)
, [profit] int
);
create table #item_table
(
[item_type] varchar(40)
);
create table #date_table
(
[yr] int
, [qtr] varchar(2)
);
insert into #sales_table values
(2010,'Q1','abc',31)
,(2010,'Q1','def',23)
,(2010,'Q1','mno',12)
,(2010,'Q1','xyz',7)
,(2010,'Q2','abc',54)
,(2010,'Q2','def',67)
,(2010,'Q2','mno',92)
,(2010,'Q2','xyz',8);
insert into #profit_table values
(2010,'Q1','abc',10)
,(2010,'Q1','def',6)
,(2010,'Q1','mno',23)
,(2010,'Q1','xyz',7)
,(2010,'Q2','abc',21)
,(2010,'Q2','def',13)
,(2010,'Q2','mno',15)
,(2010,'Q2','xyz',2);
insert into #item_table values
('abc'),('def'),('ghi'),('jkl'),('mno'),('xyz');
insert into #date_table values
(2010,'Q1'),(2010,'Q2'), (2010,'Q3'),(2010,'Q4');
SELECT
b.yr
, b.qtr
, b.item_type
, COALESCE(MAX(a.sales),0) AS sales
, COALESCE(MAX(a.avg_price),0) AS avg_price
, COALESCE(MAX(a.profit),0) AS profit
FROM
(
SELECT
dt.[yr]
,dt.[qtr]
,CASE
WHEN it.[item_type] IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER(it.[item_type])
END AS [item_type]
FROM
#date_table AS dt
CROSS JOIN
#item_table AS it
WHERE
dt.[yr] >=2010
GROUP BY
dt.[yr]
,dt.[qtr]
,CASE
WHEN it.[item_type] IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER(it.[item_type])
END
) AS b
LEFT JOIN
(SELECT [yr], [qtr],
CASE
WHEN item_type IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER([item_type])
END AS [item_type],
COUNT(sale_price) OVER (PARTITION BY yr, qtr, item_type) [sales],
AVG(sale_price) OVER (PARTITION BY yr, qtr, item_type) [avg_price],
NULL [profit]
FROM #sales_table
WHERE yr >=2010
UNION ALL
SELECT yr, qtr,
CASE
WHEN item_type IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER([item_type])
END AS [item_type],
NULL [sales],
NULL [avg_price],
SUM(profit) OVER (PARTITION BY yr, qtr, item_type) [profit]
FROM #profit_table
WHERE yr >=2010
) a
ON
a.[yr] = b.[yr]
AND
a.[qtr] = b.[qtr]
AND
a.[item_type] = b.[item_type]
GROUP BY
b.yr, b.qtr, b.item_type
ORDER BY b.yr, b.qtr, b.item_type;
结果:
+------+-----+-----------+-------+-----------+--------+
| yr | qtr | item_type | sales | avg_price | profit |
+------+-----+-----------+-------+-----------+--------+
| 2010 | Q1 | ABC | 1 | 31 | 10 |
| 2010 | Q1 | DEF | 1 | 23 | 6 |
| 2010 | Q1 | GHI | 0 | 0 | 0 |
| 2010 | Q1 | JKL | 0 | 0 | 0 |
| 2010 | Q1 | Other | 1 | 12 | 23 |
| 2010 | Q2 | ABC | 1 | 54 | 21 |
| 2010 | Q2 | DEF | 1 | 67 | 13 |
| 2010 | Q2 | GHI | 0 | 0 | 0 |
| 2010 | Q2 | JKL | 0 | 0 | 0 |
| 2010 | Q2 | Other | 1 | 92 | 15 |
| 2010 | Q3 | ABC | 0 | 0 | 0 |
| 2010 | Q3 | DEF | 0 | 0 | 0 |
| 2010 | Q3 | GHI | 0 | 0 | 0 |
| 2010 | Q3 | JKL | 0 | 0 | 0 |
| 2010 | Q3 | Other | 0 | 0 | 0 |
| 2010 | Q4 | ABC | 0 | 0 | 0 |
| 2010 | Q4 | DEF | 0 | 0 | 0 |
| 2010 | Q4 | GHI | 0 | 0 | 0 |
| 2010 | Q4 | JKL | 0 | 0 | 0 |
| 2010 | Q4 | Other | 0 | 0 | 0 |
+------+-----+-----------+-------+-----------+--------+
给你。就像评论中描述的那样 我做了一个迷你日历桌,但你会想花些时间做一个真正的。一旦你拥有了它,你就会一直使用它
if OBJECT_ID('tempdb..#sales_table', 'U') is not null
drop table #sales_table
if OBJECT_ID('tempdb..#profit_table', 'U') is not null
drop table #profit_table
if OBJECT_ID('tempdb..#item_table', 'U') is not null
drop table #item_table
if OBJECT_ID('tempdb..#date_table', 'U') is not null
drop table #date_table
create table #sales_table
(
[yr] int
, [qtr] varchar(40)
, [item_type] varchar(40)
, [sale_price] int
);
create table #profit_table
(
[yr] int
, [qtr] varchar(40)
, [item_type] varchar(40)
, [profit] int
);
create table #item_table
(
[item_type] varchar(40)
);
create table #date_table
(
[yr] int
, [qtr] varchar(2)
);
insert into #sales_table values
(2010,'Q1','abc',31)
,(2010,'Q1','def',23)
,(2010,'Q1','mno',12)
,(2010,'Q1','xyz',7)
,(2010,'Q2','abc',54)
,(2010,'Q2','def',67)
,(2010,'Q2','mno',92)
,(2010,'Q2','xyz',8);
insert into #profit_table values
(2010,'Q1','abc',10)
,(2010,'Q1','def',6)
,(2010,'Q1','mno',23)
,(2010,'Q1','xyz',7)
,(2010,'Q2','abc',21)
,(2010,'Q2','def',13)
,(2010,'Q2','mno',15)
,(2010,'Q2','xyz',2);
insert into #item_table values
('abc'),('def'),('ghi'),('jkl'),('mno'),('xyz');
insert into #date_table values
(2010,'Q1'),(2010,'Q2'), (2010,'Q3'),(2010,'Q4');
SELECT
b.yr
, b.qtr
, b.item_type
, COALESCE(MAX(a.sales),0) AS sales
, COALESCE(MAX(a.avg_price),0) AS avg_price
, COALESCE(MAX(a.profit),0) AS profit
FROM
(
SELECT
dt.[yr]
,dt.[qtr]
,CASE
WHEN it.[item_type] IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER(it.[item_type])
END AS [item_type]
FROM
#date_table AS dt
CROSS JOIN
#item_table AS it
WHERE
dt.[yr] >=2010
GROUP BY
dt.[yr]
,dt.[qtr]
,CASE
WHEN it.[item_type] IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER(it.[item_type])
END
) AS b
LEFT JOIN
(SELECT [yr], [qtr],
CASE
WHEN item_type IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER([item_type])
END AS [item_type],
COUNT(sale_price) OVER (PARTITION BY yr, qtr, item_type) [sales],
AVG(sale_price) OVER (PARTITION BY yr, qtr, item_type) [avg_price],
NULL [profit]
FROM #sales_table
WHERE yr >=2010
UNION ALL
SELECT yr, qtr,
CASE
WHEN item_type IN ('mno', 'xyz') THEN 'Other'
ELSE UPPER([item_type])
END AS [item_type],
NULL [sales],
NULL [avg_price],
SUM(profit) OVER (PARTITION BY yr, qtr, item_type) [profit]
FROM #profit_table
WHERE yr >=2010
) a
ON
a.[yr] = b.[yr]
AND
a.[qtr] = b.[qtr]
AND
a.[item_type] = b.[item_type]
GROUP BY
b.yr, b.qtr, b.item_type
ORDER BY b.yr, b.qtr, b.item_type;
结果:
+------+-----+-----------+-------+-----------+--------+
| yr | qtr | item_type | sales | avg_price | profit |
+------+-----+-----------+-------+-----------+--------+
| 2010 | Q1 | ABC | 1 | 31 | 10 |
| 2010 | Q1 | DEF | 1 | 23 | 6 |
| 2010 | Q1 | GHI | 0 | 0 | 0 |
| 2010 | Q1 | JKL | 0 | 0 | 0 |
| 2010 | Q1 | Other | 1 | 12 | 23 |
| 2010 | Q2 | ABC | 1 | 54 | 21 |
| 2010 | Q2 | DEF | 1 | 67 | 13 |
| 2010 | Q2 | GHI | 0 | 0 | 0 |
| 2010 | Q2 | JKL | 0 | 0 | 0 |
| 2010 | Q2 | Other | 1 | 92 | 15 |
| 2010 | Q3 | ABC | 0 | 0 | 0 |
| 2010 | Q3 | DEF | 0 | 0 | 0 |
| 2010 | Q3 | GHI | 0 | 0 | 0 |
| 2010 | Q3 | JKL | 0 | 0 | 0 |
| 2010 | Q3 | Other | 0 | 0 | 0 |
| 2010 | Q4 | ABC | 0 | 0 | 0 |
| 2010 | Q4 | DEF | 0 | 0 | 0 |
| 2010 | Q4 | GHI | 0 | 0 | 0 |
| 2010 | Q4 | JKL | 0 | 0 | 0 |
| 2010 | Q4 | Other | 0 | 0 | 0 |
+------+-----+-----------+-------+-----------+--------+
您可以使用
select Upper(item\u type)
缩短查询开始。就我个人而言,我会从一个日历表开始(从谷歌开始)。您需要使用该表和item_表
作为基本数据集(使用a
交叉连接),然后
左连接到其他表。然后,可以对聚合值使用ISNULL
。先去研究一下,然后把你尝试过的和你挣扎过的地方贴出来。@GuidoG,这不是重点。如果您可能注意到,我并没有将项目类型转换为大写,而是将某些项目类型用棍棒固定在公共列“Other”中。因此,您可以先在Case中用棍棒固定,然后将所有其他符号@GuidoG用棍棒固定。一旦我的实际问题(无法获得预期的输出)得到解决,当然可以这样做。你可以使用select Upper(item_type)
缩短查询开始。就我个人而言,我会从一个日历表开始(从谷歌开始)。您需要使用该表和item_表
作为基本数据集(使用a
交叉连接),然后
左连接到其他表。然后,可以对聚合值使用ISNULL
。先去研究一下,然后把你尝试过的和你挣扎过的地方贴出来。@GuidoG,这不是重点。如果您可能注意到,我并没有将项目类型转换为大写,而是将某些项目类型用棍棒固定在公共列“Other”中。因此,您可以先在Case中用棍棒固定,然后将所有其他符号@GuidoG用棍棒固定。一旦我的实际问题(无法获得预期的产出)得到解决,我肯定会这样做。我很高兴这有帮助,@RAVI。感谢您发布所有详细信息。结构良好的问题使回答更容易!“我很高兴这有帮助,”拉维说。感谢您发布所有详细信息。结构良好的问题使回答更容易!