我需要什么 SQL 魔法才能将一列变成多列?
我需要打印一些票据,每张票据都有足够的空间来容纳一组客户详细信息以及该客户订购的最多五件商品的代码。订购超过五件商品的顾客将获得多张门票。因此,从这样的订单表中,
Customer | Item ---------|------ Bob | FTMCH Bob | ZORP Bob | KLUGE Carol | FTMCH Carol | MEEP Carol | ZORP Ted | FOON Ted | SMOCK Alice | ORGO Carol | SQICK Carol | BLECH Carol | KLUGE Carol | GLURP
我需要一个返回以下内容的查询:
Customer | Item1 | Item2 | Item3 | Item4 | Item5 ---------|-------|-------|-------|-------|------ Alice | ORGO | null | null | null | null Bob | FTMCH | ZORP | KLUGE | null | null Carol | FTMCH | MEEP | ZORP | SQICK | BLECH Carol | KLUGE | GLURP | null | null | null Ted | FOON | SMOCK | null | null | null
有人能帮我解决这个问题的 SQL 吗? OpenOffice.org Base 中的 HSQL 嵌入式数据库(如果有影响的话)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好的,这工作得很好:
它使得:
感谢所有在这里和 询问 Metafilter。
(后续编辑:)
天哪,这只会变得更糟 :-(
事实证明,业务规则允许同一客户多次订购同一商品,而且所有这些未完成的订单将包含在一组门票中,所以我的玩具表应该看起来更像这样:
卡罗尔的多个 MEEP 扰乱了原始解决方案中的排名逻辑,我最终得到了以下可怕的怪物
: 我想它可以完成这项
工作,但我感到很幸运,所涉及的数据库总是很小(几千行)。
从精神上来说,我是一个嵌入式系统人员,而不是数据库人员。任何以此为生的人都可以告诉我这种废话是否常见吗?带有四个嵌套 SELECT 和 LEFT JOIN 的查询是否值得在 Daily WTF 上提及?
OK, this works well enough:
It makes this:
Thanks to all who helped, both here and at Ask Metafilter.
(Followup edit:)
Jesus, this just gets worse :-(
Turns out the business rules allow the same customer to order the same item on multiple occasions, and that all outstanding orders are to be included on the one set of tickets. So my toy table should have looked more like this:
Carol's multiple MEEPs bugger the ranking logic in the original solution, and I've ended up with the following hideous monster:
which makes this:
It does the job, I guess, but I'm feeling pretty lucky that the database involved is always going to be quite small (a few thousand rows).
Spiritually I'm an embedded-systems guy, not a database guy. Can anybody who does this for a living tell me whether this kind of nonsense is common? Would a query with four nested SELECTs and a LEFT JOIN merit a mention on the Daily WTF?
我相信这仅适用于 T-SQL,但您可以使用 PIVOT: http: //msdn.microsoft.com/en-us/library/ms177410.aspx
我做了类似的事情,将日期列表变成计算列。
I believe this is only usable for T-SQL, but you can use PIVOT: http://msdn.microsoft.com/en-us/library/ms177410.aspx
I did something similar with a list of dates becoming the columns for calculations.
不完全是你问的,MySQL 而不是 OpenOffice,但可能会给你一个想法或者其他人可以处理它:
输出:
Not exactly what you asked, and MySQL rather than OpenOffice, but might give you an idea or someone else could work on it :
Output :
这可以帮助您完成大部分任务,但不能处理
Carol
的重复订单。如果还有其他要分组的内容,例如OrderID
或OrderDate
,那么这很容易做到。你能发布完整的架构吗?输出:
This gets you most of the way there, but does not handle the duplicate order for
Carol
. That would be easy to do if there was something else to group on, likeOrderID
orOrderDate
. Can you post the full schema?Output:
这种需求并不罕见,并且可以在 SQL 中合理地提供。但有两个问题阻碍了你。
1) 您输入了一个 SQL 标签,这意味着 ISO/IEC/ANSI 标准 SQL。正确的使用方法是游标或游标替代(while 循环,它执行相同的操作,但速度更快)。这避免了所有这些外部联接和处理大量结果集;然后用 GROUP BY 等将其提交。它还处理重复项,主要是因为它首先创建它们(通过别名表的这五个版本)。是的,情况会变得更糟,当数据库合理填充时,它将成为性能消耗者。
2)关系数据库中不允许重复,即。在你的源表中;您需要使行唯一(并且那些键/列不显示)。尝试通过代码消除重复项是没有用的。如果这一点得到纠正,那么所有重复项(真实的重复项和由不良代码创建的重复项)都可以被消除。
使用子查询也可以更优雅地满足此要求;只是这里需要两层嵌套,一层用于构建教学项目列,两层用于获取排名或位置。并且(标准 SQL 构造)预先假设您有一个关系数据库(没有重复的行)。如果您不习惯 SQL,则 Eeek 因素较高。这就是大多数程序员使用光标或光标替代品的原因。
但是,如果您没有 SQL 及其基本功能(HSQL 是一些不标准的实现),那么我们就不会使用相同的工具包。我能提供的SQL代码不会为你运行,我们将继续来回。
(也许我们应该有一个“psuedo-SQL”标签。)
ID
列防止重复???在业界的某些部分,有一个普遍存在的神话:这种效果,归功于数据库初学者写的书籍。像往常一样,神话没有科学依据。让我们尝试一个简单的测试。
That's a pure, unarguable duplicate row. The simple fact is. the
Id
column provides a row number, but does nothing to prevent duplicate rows. For that you need an Unique Index on the columns that determine uniqueness, as identified in the data model, for every relational table in the database (by definition, if the rows are not unique, it is not a Relational table). Otherwise it is just a file storage system.我可能会识别另一种形式的数据完整性(重复)。
All are preventable in SQL.
The requirement is not uncommon, and can be supplied reasonably in SQL. But you have two issues blocking you.
1) You've entered an SQL tag, that means ISO/IEC/ANSI Standard SQL. The correct method to use is a cursor or cursor substitute (while loop, which does the same thing, but is faster). That avoids all these outer joins and handling massive result sets; then beating it into submission with GROUP BYs, etc. It also handles duplicates, mainly because it does it create them in the first place (via those five versions of the aliased table). And yes, it will keep getting worse, and when the database is reasonably populated it will be a performance hog.
2) Duplicates are not allowed in a Relational database, ie. in your source tables; you need to make the rows unique (and those keys/columns is not shown). No use trying to eliminate duplicates via code. If that is corrected, then all duplicates (real and created by the poor code) can be eliminated.
This requirement can also be supplied more elegantly using Subqueries; except that here you need two levels of nesting, one to build teach Item column, and two to obtain rank or Position. And that (standard SQL construct) pre-supposes that you have a Relational database (no duplicate rows). High Eek factor if you are not used to SQL. Which is why most coders use a cursor or cursor substitute.
But if you do not have SQL, its basic capabilities, (HSQL being some sub-standard implementation), then we are not using the same tool kit. The SQL code I can provide will not run for you, and we will keep going back and forth.
(Maybe we should have a "psuedo-SQL" tag.)
ID
Column Prevents Duplicates ???There is a myth that is prevalent in some parts of the industry, to that effect, due to books written by database beginners. As usual, myths have no scientific basis. Let's try a simple test.
That's a pure, unarguable duplicate row. The simple fact is. the
Id
column provides a row number, but does nothing to prevent duplicate rows. For that you need an Unique Index on the columns that determine uniqueness, as identified in the data model, for every relational table in the database (by definition, if the rows are not unique, it is not a Relational table). Otherwise it is just a file storage system.There is another form of data integrity (duplication) which I might identify while I am at it.
All are preventable in SQL.