这是一个简单而常见的工作方案,我很感激一些意见。
假设我正在为宠物秀的主人制作报告,他们想知道他们的哪些顾客已经购买了每只宠物的数量。在这种情况下,我唯一的工具是SQL,可以将我的查询输出到电子表格。
作为店主,我可能希望报告形式为:
Customer Dog Cat Rabbit
1 2 3 0
2 0 1 1
3 1 2 0
4 0 0 1
如果有一天我决定库存金鱼,那么报告现在就应该出来了。
Customer Dog Cat Rabbit Goldfish
1 2 3 0 0
2 0 1 1 0
3 1 2 0 0
4 0 0 1 0
5 0 0 0 1
但正如您可能知道的那样,以这种方式运行的查询将涉及某种形式的动态代码生成,并且将更难做到。
最简单的查询将按以下方式工作: 交叉加入客户和宠物,外部加入销售,集团等 并生成:
Customer Pet Quantity
1 Dog 2
1 Cat 3
1 Rabbit 0
1 Goldfish 0
2 Dog 0
2 Cat 1
2 Rabbit 1
...etc
a)我如何向店主解释他们想要的报告“难以”产生?我并不想说它更难读,但写起来更难。
b)我试图向客户解释的概念的名称是什么(以帮助我的谷歌搜索)?
答案 0 :(得分:2)
概念的名称是“交叉表”,可以通过多种方式完成。
MS Access具有SQL专有扩展,可以实现这一目标。 SQL pre-2k5有一个CASE技巧和2k5后来有PIVOT,但我认为你仍然需要知道列是什么。
答案 1 :(得分:1)
有些数据库确实支持某种创建交叉表的方法,但我认为最需要知道的 提前列,所以你必须修改SQL(并获得支持这种扩展的数据库)。
另一种方法是创建一个程序,该程序将对第二个“简单”表进行后处理,以使客户端作为输出交叉表。与修改SQL或动态生成SQL相比,这可能更容易,也更通用。
关于解释问题的方法......你可以在Excel中显示它们需要多少步骤来获得所需的结果:
然后说SQL只为你提供源数据,所以它当然更有效。
答案 2 :(得分:1)
此概念称为pivoting
SQL
假设您的数据是以具有固定结构的关系表示的。
就像,平等是二元关系,“顾客有这种类型的许多宠物”是三元关系等等。
当您看到此结果集时:
Customer Pet Quantity
1 Dog 2
1 Cat 3
1 Rabbit 0
1 Goldfish 0
2 Dog 0
2 Cat 1
2 Rabbit 1
,它实际上是由域值的所有可能组合定义的关系。
例如,客户1
(域customers id's
)拥有2
属的positive numbers
(域dog
)宠物(域名pets
} )。
我们在结果集中看不到这样的行:
Customer Pet Quantity
1 Dog 3
Pete Wife 0.67
,因为第一行为false(客户1
没有3
项dog
,但2
),第二行的值不在他们的域名范围。
SQL
范例意味着在发出查询时定义了您的关系,并且返回的每一行都完全定义了关系。
SQL Server 2005+
可以将行映射到列中(这就是您想要的),但在设计查询(未运行)时应该知道列数。
通常,您尝试构建的报告是使用报告软件构建的,该软件知道如何将关系SQL
结果集转换为漂亮的人类可读报告。
答案 3 :(得分:1)
我一直称这种旋转,但这可能不是正式名称。
无论它被称为什么,你都可以用普通的SQL做几乎所有这些。
SELECT customer, count(*), sum(CASE WHEN pet='dog' THEN 1 ELSE 0 END) as dog, sum(case WHEN pet='cat' THEN 1 ELSE 0 END) as cast FROM customers join pets
显然缺少的是动态列。我不知道这是否可以在直接SQL中使用,但在存储过程中当然可以在首次查询宠物列表后动态生成查询。查询构建在一个字符串中,然后该字符串用于创建预准备语句。