补充:巧不巧,大家看下就知道了,如果觉得不巧,再拍砖也不迟,^_^
这是我进公司时SQL培训出的题.其中的pubs为SQLServer的示例数据库.(向SQLServer中添加pubs的代码见附件)
查看 stores,sales and titles 关联后的表
1
with temp as
2
(
3
SELECT dbo.stores.stor_id,dbo.stores.stor_name,dbo.titles.type,dbo.sales.qty
4
FROM dbo.sales
5
INNER JOIN dbo.stores
6
ON dbo.sales.stor_id=dbo.stores.stor_id
7
INNER JOIN dbo.titles
8
ON dbo.sales.title_id=dbo.titles.title_id
9
)
with temp as2
(3
SELECT dbo.stores.stor_id,dbo.stores.stor_name,dbo.titles.type,dbo.sales.qty4
FROM dbo.sales 5
INNER JOIN dbo.stores6
ON dbo.sales.stor_id=dbo.stores.stor_id7
INNER JOIN dbo.titles8
ON dbo.sales.title_id=dbo.titles.title_id9
)//如果对temp进行查询,则结果为:

一、常规的思路:
利用子查询
1
select distinct stor_id,stor_name
2
from temp as t
3
where [type]= 'business' and exists
4
(
5
select * from temp where stor_id = t.stor_id and [type] = 'mod_cook'
6
)
select distinct stor_id,stor_name2
from temp as t3
where [type]= 'business' and exists4
(5
select * from temp where stor_id = t.stor_id and [type] = 'mod_cook'6
)
这种方法容易理解,但是执行效率低,会出现多次扫描表!我们来看第二种思路(我的解法)
二、利用PIVOT函数,来个行列转换:
把type的business与mod_cook列值转换成表的字段,就可以直接用where business is not null and mod_cook is not null 直接筛取了
详细过程:
1.转置
1
SELECT stor_id,stor_name ,[business],[mod_cook]
2
FROM temp AS S
3
PIVOT
4
(
5
SUM(qty)
6
FOR [type] in([business],[mod_cook])
7
) AS R
8
9
SELECT stor_id,stor_name ,[business],[mod_cook]2
FROM temp AS S3
PIVOT4
(5
SUM(qty)6
FOR [type] in([business],[mod_cook])7
) AS R8

9

结果:

2.据条件筛:WHERE [business] IS NOT NULL AND [mod_cook] IS NOT NULL
结果:

应题目需要,修改后的代码完整如下:
1
SELECT stor_id,stor_name
2
FROM temp AS S
3
PIVOT
4
(
5
SUM(qty)
6
FOR [type] in([business],[mod_cook])
7
) AS R
8
WHERE [business] IS NOT NULL AND [mod_cook] IS NOT NULL
9
10
SELECT stor_id,stor_name2
FROM temp AS S3
PIVOT4
(5
SUM(qty)6
FOR [type] in([business],[mod_cook])7
) AS R8
WHERE [business] IS NOT NULL AND [mod_cook] IS NOT NULL9

10

最终结果:

这个种方法比较拗,但利用了PIVOT转置行列避免了多次扫描表,效率不错!
也是新手,如果有不对的或是不合理的地方大家多拍砖!
附:向数据库添加Pubs实例库的代码:https://files.cnblogs.com/FojamesChen/pubs.rar

