尝试编写语句,在单个语句中选择all(*
)并将同一数据库和同一个表中的一列相加,具体取决于条件。
写了这样的陈述(基于这个Multiple select statements in Single query)
SELECT ( SELECT SUM(Amount) FROM 2_1_journal), ( SELECT * FROM 2_1_journal WHERE TransactionPartnerName = ? )
我了解SELECT SUM(Amount) FROM 2_1_journal
将对Amount
列中的所有值求和(不基于编码)。
但首先要了解什么是正确的陈述
使用上述语句获取错误SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
无法理解错误消息。根据此处的建议MySQL - Operand should contain 1 column(s)了解子查询SELECT * FROM 2_1_journal WHERE TransactionPartnerName = ?
必须只选择一列?
尝试将语句更改为此SELECT ( SELECT * FROM 2_1_journal WHERE TransactionPartnerName = ? ), ( SELECT SUM(Amount) FROM 2_1_journal)
,但得到相同的错误......
什么是正确的陈述?
答案 0 :(得分:2)
SELECT *, (SELECT SUM(Amount) FROM 2_1_journal)
FROM 2_1_journal
WHERE TransactionPartnerName = ?
这将从整个表中选择总结Amount
并“追加”TransactionPartnerName
是您在客户端代码中绑定的参数的所有行。
如果要将总和限制为与您选择的行相同的条件,请将其包括在内:
SELECT *, (SELECT SUM(Amount) FROM 2_1_journal WHERE TransactionPartnerName = ?)
FROM 2_1_journal
WHERE TransactionPartnerName = ?
完全不同的是:像2_1_journal
这样的表名是数据库设计损坏的强有力指标。如果您可以重做它,您应该研究如何正确地规范化数据库。它很可能会多次收回。
关于规范化(稍后补充):
由于当前设计使用表名中的键(例如2
中的1
和2_1_journal
),我将很快说明我认为您可以大大改进该设计。让我们说表2_1_journal
有以下数据(我只是在这里猜测,因为这些表尚未在任何地方描述):
title | posted | content
------+------------+-----------------
Yes! | 2013-01-01 | This is just a test
2nd | 2013-01-02 | Another test
此内容属于公司2
中的用户1
。但是嘿!如果您查看行,则无法找到此数据属于公司2
中的用户1
的事实。
问题是此设计违反了数据库设计的最基本原则之一:不要在对象(此处为:表)名称中使用键。如果你必须在添加新内容时创建新表,那么明确指出某些内容是非常错误的。在这种情况下,添加新用户或新公司需要添加新表。
这个问题很容易解决。创建名为journal
的一个表。接下来,使用相同的列,但添加另外两列:
company | user | title | posted | content
--------+------+-------+------------+-----------------
1 | 2 | Yes! | 2013-01-01 | This is just a test
1 | 2 | 2nd | 2013-01-02 | Another test
这样做意味着:
comments
添加到所有x_y_journal
表,但忘记5313_4324_journal
导致用户5313
登录时应用程序仅打开 。这是您不想处理的问题。我不是写这个,因为这是个人品味的问题。数据库只是为处理如上所述的表格而设计的。将对象键作为表名的一部分使用的设计存在许多与之相关的其他难以处理的问题。