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; 
+0

不完全。我甚至没有100%理解它的逻辑,但我跑它进行了一个快速测试,并计算出两个截然不同的有用值。但是我基于SELECT查询的结果进行计数。如果我将LIMIT 10添加到最后(并且忽略TimeLogged位),那么我希望每行都包含一个10的GrandTotal。我想要的数字不是基于表中的某些内容,而是基于什么我选择了它,我不想做一个子查询,因为我可能需要多个不同的计数,而且会变得很难看。 – 2010-09-29 23:36:45

+0

@Hammer - 如果添加WITH WITH ROLLUP?会怎样? – 2010-09-29 23:38:17

+0

将它添加到示例中似乎没有改变我的结果,但WITH ROLLUP实际上可能是关键。如果我得到所有我想要的结果和一列仅计1(结果由唯一标识符分组),并且WITH ROLLUP可以让他们计算结果的数量,那么我的框架允许(实际上是强制)我得到最后一行的列值,当我想要一个单一的值,而不是他们的列表。给我几个尝试去适应 - 我对GROUPING和ROLLUP都有点新鲜感。 – 2010-09-29 23:54:18

您使用的是访问数据库的API应该能够向您报告是如何返回多行 - 比方说,如果你正在运行的Perl,你可以做这样的事情:

my $sth = $dbh->prepare("SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT'"); 
my $rv = $sth->execute(); 
my $rows = $sth->rows; 
+0

我不认为这是他的问题。他需要运行两个查询并将它们返回到一个结果集中。 – 2010-09-29 23:25:33

+0

我实际上并没有使用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'; 

这是一个黑客位,但你正在试图做的是不理想......

+1

他试图做的事很可怕,错误,但UNION是做错事的非常好的工具。它可以将任何数据粘贴在一起,只要它是正确的形状;它并不关心语义。 – 2010-09-30 00:01:05

+0

这似乎并不奏效(它给出了一个有关在'字段列表'中找不到'Cnt'的错误),但它看起来像第二个SELECT也会给出关于具有GROUP BY函数(COUNT)的错误与非GROUP列一起。在输入回复时,我意识到我可以使用GROUP BY NULL,这对我的事业确实非常有帮助。我想我可以通过嵌套SELECT中的LEFT JOIN得到一些结果,这些结果会为每个计数重复一次查询,但这可能是必要的,并且回顾我必须计算的事情从不像主查询那么复杂。 – 2010-09-30 00:53:37

+1

@Hammer Bro:尝试在Phil的查询中将'Cnt = 0'更改为'0 Cnt'。 – 2010-09-30 13:20:47

分组由Tabl.id我不相信会弄乱结果。尝试一下,看看你是否想要什么。

+0

这就是我第一次尝试,但是这将返回一个结果行与单个Tabl行相匹配的计数,给我一堆1。我想要的是每个Tabl行都具有所有不同结果行的全部计数,试图让SQL通过使用自联接来计算SELECT查询返回的行数。我怀疑这是获取这些信息的最好方法,但这是我能想到的最好的方法,单SELECT查询限制有点不同寻常。 – 2010-09-29 23:48:22