MySQL的:包括SELECT查询的盘点结果为一列(不分组)
我有一个简单的发送报告的框架,基本上做以下的事情: 它执行SELECT查询,它使基于结果的一些文本格式的表格它发送一封电子邮件,并执行UPDATE查询。MySQL的:包括SELECT查询的盘点结果为一列(不分组)
该系统是一个较旧的一个,所有的行动是硬编码的推广。然而,在将所有我想要做的逻辑推入SELECT查询中时,我遇到了一个问题。
之前,我可以说得到大部分的信息为我的文字表:
SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT';
然后,当我需要的电子邮件额外的数量,也这样做:
SELECT COUNT(*) FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon';
现在,我不再拥有多个SELECT查询的好处了。我想要做的是一样的东西:
SELECT Tabl.Name, Tabl.Address, COUNT(Results.UID) AS Totals
FROM Databas.Tabl
LEFT JOIN Databas.Tabl Results
ON Tabl.UID = Results.UID
AND Results.TimeLogged='Noon'
WHERE Status='URGENT';
这一点,至少在我的头上,说要拿到选择,也有一些条件的所有行的总数。
在现实中,虽然,这给我的“1140 - 混合组列没有GROUP列非法的,如果没有GROUP BY”的错误。问题是,我不想GROUP BY。我希望COUNT冗余地重复发现其TimeLogged ='Noon'的SELECT结果的数量。或者我想删除AND子句并在SELECT语句的结果中包含该SELECT语句找到的结果的数量。
GROUP BY不是办法,因为这会导致它得到的只有谁在一些列的值相同的行数。而COUNT甚至可能不是这样的方式,尽管这是想到的。 FOUND_ROWS()不会执行这个技巧,因为它需要是辅助查询的一部分,我只能得到一个(加上没有LIMIT参与),而且由于它是SELECT语句,因此ROW_COUNT()似乎不起作用。
我可以从错误的角度完全可以接近它。但是我想要做的是在单个查询中获取有关SELECT查询结果的COUNT类型信息,以及SELECT查询返回的所有其他信息。
===这就是我这么远===
SELECT Tabl.Name, Tabl.Address, Results.Totals
FROM Databas.Tabl
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus
FROM Databas.Tabl
WHERE TimeLogged='Noon'
GROUP BY NULL) Results
ON 0 = Results.Bonus
WHERE Status='URGENT';
这确实使用子查询,这是我最初希望避免的,但现在认识到,希望可能是愚蠢的。另外,由于COUNT条件全部在一个表上,COUNTING SELECT子查询似乎比主查询更便宜,但我正在使用的真正SELECT必须连接到多个不同的表以获取派生信息。
关键的实现是我可以GROUP BY NULL,它将返回一个单一的结果,以便COUNT(*)实际上会捕获所有内容,并且我可以强制与该列关联,只需使用0在两张桌子上。
它看起来这是我将要使用的解决方案,但我不能真正接受它作为一个答案,直到明天。感谢所有的帮助。
SELECT Tabl.Name, Tabl.Address, Results.Totals
FROM Databas.Tabl
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus
FROM Databas.Tabl
WHERE TimeLogged='Noon'
GROUP BY NULL) Results
ON 0 = Results.Bonus
WHERE Status='URGENT';
我想到了这一点,这要归功于由多个答案产生的想法,尽管它实际上并不是任何一个的直接结果。为什么这样做需要我在原文的编辑中解释过,但我希望能够通过正确的答案解决问题,以防其他人想要执行这种愚蠢的操作。感谢所有的帮助。
这是否做你所需要的?
SELECT Tabl.Name ,
Tabl.Address ,
COUNT(Results.UID) AS GrandTotal,
COUNT(CASE WHEN Results.TimeLogged='Noon' THEN 1 END) AS NoonTotal
FROM Databas.Tabl
LEFT JOIN Databas.Tabl Results
ON Tabl.UID = Results.UID
WHERE Status ='URGENT'
GROUP BY Tabl.Name,
Tabl.Address
WITH ROLLUP;
您使用的是访问数据库的API应该能够向您报告是如何返回多行 - 比方说,如果你正在运行的Perl,你可以做这样的事情:
my $sth = $dbh->prepare("SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT'");
my $rv = $sth->execute();
my $rows = $sth->rows;
我不认为这是他的问题。他需要运行两个查询并将它们返回到一个结果集中。 – 2010-09-29 23:25:33
我实际上并没有使用API - 只是定期扫描目录中的.properties文件,这些文件指定了SELECT查询,表格格式信息,电子邮件格式信息和UPDATE查询。如果我想要一个包含所有名称的表,我可以在该行上放置$ {Name},并从ResultSet中选择“Name”。但是,这只能从一个SELECT查询中获得信息,所以我试图找到一种方法来处理这个不寻常的COUNT信息到单个SELECT语句,因此我可以为电子邮件主题获取$ {ResultCount}。 – 2010-09-29 23:45:11
你或许可以做一个联合。您必须将一列添加到原始查询中,然后在其中选择0,然后使用您的第二个查询返回单个列的UNION。要做到这一点,第二个查询也必须选择空字段来匹配第一个。
SELECT Cnt = 0, Name, Address FROM Databas.Tabl WHERE Status='URGENT'
UNION ALL
SELECT COUNT(*) as Cnt, Name='', Address='' FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon';
这是一个黑客位,但你正在试图做的是不理想......
他试图做的事很可怕,错误,但UNION是做错事的非常好的工具。它可以将任何数据粘贴在一起,只要它是正确的形状;它并不关心语义。 – 2010-09-30 00:01:05
这似乎并不奏效(它给出了一个有关在'字段列表'中找不到'Cnt'的错误),但它看起来像第二个SELECT也会给出关于具有GROUP BY函数(COUNT)的错误与非GROUP列一起。在输入回复时,我意识到我可以使用GROUP BY NULL,这对我的事业确实非常有帮助。我想我可以通过嵌套SELECT中的LEFT JOIN得到一些结果,这些结果会为每个计数重复一次查询,但这可能是必要的,并且回顾我必须计算的事情从不像主查询那么复杂。 – 2010-09-30 00:53:37
@Hammer Bro:尝试在Phil的查询中将'Cnt = 0'更改为'0 Cnt'。 – 2010-09-30 13:20:47
分组由Tabl.id我不相信会弄乱结果。尝试一下,看看你是否想要什么。
这就是我第一次尝试,但是这将返回一个结果行与单个Tabl行相匹配的计数,给我一堆1。我想要的是每个Tabl行都具有所有不同结果行的全部计数,试图让SQL通过使用自联接来计算SELECT查询返回的行数。我怀疑这是获取这些信息的最好方法,但这是我能想到的最好的方法,单SELECT查询限制有点不同寻常。 – 2010-09-29 23:48:22
不完全。我甚至没有100%理解它的逻辑,但我跑它进行了一个快速测试,并计算出两个截然不同的有用值。但是我基于SELECT查询的结果进行计数。如果我将LIMIT 10添加到最后(并且忽略TimeLogged位),那么我希望每行都包含一个10的GrandTotal。我想要的数字不是基于表中的某些内容,而是基于什么我选择了它,我不想做一个子查询,因为我可能需要多个不同的计数,而且会变得很难看。 – 2010-09-29 23:36:45
@Hammer - 如果添加WITH WITH ROLLUP?会怎样? – 2010-09-29 23:38:17
将它添加到示例中似乎没有改变我的结果,但WITH ROLLUP实际上可能是关键。如果我得到所有我想要的结果和一列仅计1(结果由唯一标识符分组),并且WITH ROLLUP可以让他们计算结果的数量,那么我的框架允许(实际上是强制)我得到最后一行的列值,当我想要一个单一的值,而不是他们的列表。给我几个尝试去适应 - 我对GROUPING和ROLLUP都有点新鲜感。 – 2010-09-29 23:54:18