[英]SQL Combining Multiple SELECT Statements
I am trying to build an SQLite query that will collect statistics from a single table. 我正在尝试构建一个SQLite查询,它将从单个表中收集统计信息。
The table holds a log, of sorts, with several entries per day. 该表包含各种日志,每天有几个条目。 I need to get a separate row for each day within the search parameters and then compile the totals of rows within those dates with certain boolean values. 我需要在搜索参数中每天获得一个单独的行,然后使用某些布尔值编译这些日期内的行总数。
Here is the query I have so far: 这是我到目前为止的查询:
SELECT DATE(DateTime) AS SearchDate,
(SELECT COUNT() AS Total
FROM CallRecords
WHERE DATE(DateTime)
BETWEEN '2017-08-27' AND '2017-09-02'
GROUP BY DATE(DateTime)
ORDER BY Total DESC) AS Total,
(SELECT COUNT() AS Total
FROM CallRecords
WHERE NoMarket = 1
AND DATE(DateTime)
BETWEEN '2017-08-27' AND '2017-09-02'
GROUP BY DATE(DateTime)
ORDER BY Total DESC) AS NoMarkets,
(SELECT COUNT() AS Total
FROM CallRecords
WHERE Complaint = 1
AND DATE(DateTime)
BETWEEN '2017-08-27' AND '2017-09-02'
GROUP BY DATE(DateTime)
ORDER BY Total DESC) AS Complaints,
(SELECT COUNT() AS Total
FROM CallRecords
WHERE Voicemail = 1
AND DATE(DateTime)
BETWEEN '2017-08-27' AND '2017-09-02'
GROUP BY DATE(DateTime)
ORDER BY Total DESC) AS Voicemails
FROM CallRecords
WHERE DATE(DateTime) BETWEEN '2017-08-27' AND '2017-09-02'
GROUP BY SearchDate
And the output: 并输出:
8/28/2017 175 27 11
8/29/2017 175 27 11
8/30/2017 175 27 11
8/31/2017 175 27 11
9/1/2017 175 27 11
As you can see, it is properly getting each individual date, but the totals for the columns is incorrect. 正如您所看到的,它正确地获取每个日期,但列的总数不正确。
Obviously, I am missing something in my query, but I am not sure where. 显然,我在查询中遗漏了一些内容,但我不知道在哪里。 Is there a better way to perform this query? 有没有更好的方法来执行此查询?
EDIT: I have looked into several of the other questions with near-identical titles here, but I have not found anything similar to what I'm looking for. 编辑:我已经在这里查看了几个其他几乎相同标题的问题,但我没有发现任何类似于我正在寻找的东西。 Most seem much more complicated than what I'm trying to accomplish. 大多数似乎比我想要完成的要复杂得多。
It looks like you have a mess of columns in your CallRecords
table with names like Complaint
and Voicemail
, each of which classifies a call. 看起来你的CallRecords
表中有一堆乱七八糟的列,其名称包括Complaint
和Voicemail
,每个列都对一个电话进行分类。
It looks like those columns have the value 1 when relevant. 看起来这些列在相关时具有值1。
So this query should probably help you. 所以这个查询应该可以帮到你。
SELECT DATE(DateTime) AS SearchDate,
COUNT(*) AS Total,
SUM(NoMarket = 1) AS NoMarkets,
SUM(Complaint = 1) AS Complaints,
SUM(Voicemail = 1) AS Voicemails
FROM CallRecords
WHERE DateTime >= '2017-08-27'
AND DateTime < '2017-09-02' + INTERVAL 1 DAY
GROUP BY DATE(DateTime)
Why does this work? 为什么这样做? Because in MySQL a Boolean expression like Voicemail = 1
has the value 1
when it's true and 0
when it's false. 因为在MySQL中,像Voicemail = 1
这样的布尔表达式在值为1
时为1
,在为false时为0
。 You can sum those values up quite nicely. 你可以很好地总结这些值。
Why is it faster than what you have? 为什么它比你拥有的更快? Because DATE(DateTime) BETWEEN this AND that
can't exploit an index on DateTime
. 因为DATE(DateTime) BETWEEN this AND that
无法利用DateTime
上的索引。
Why is it correct for the end of your date range? 为什么在日期范围结束时它是正确的? Because DateTime < '2017-09-02' + INTERVAL 1 DAY
pulls in all the records up until, but not including, midnight, on the day after your date range. 因为DateTime < '2017-09-02' + INTERVAL 1 DAY
将所有记录拉到日期范围之后的第二天,但不包括午夜。
If you're using Sqlite, you need AND DateTime < date('2017-09-02', '+1 day')
. 如果您使用的是Sqlite,则需要AND DateTime < date('2017-09-02', '+1 day')
。 The + INTERVAL 1 DAY
stuff is slightly different there. + INTERVAL 1 DAY
东西在那里略有不同。
you can doing like this , although i wrote in SQL server 你可以这样做,虽然我在SQL服务器上写道
SELECT DATE(DateTime) AS SearchDate,
COUNT() AS TOTAL,
SUM(CASE WHEN NoMarket = 1 THEN 1 ELSE 0 END) AS NoMarkets,
SUM(CASE WHEN Complaint = 1 THEN 1 ELSE 0 END) AS Complaints,
SUM(CASE WHEN Voicemail = 1 THEN 1 ELSE 0 END) AS Voicemails
FROM CallRecords
WHERE DATE(DateTime) BETWEEN '2017-08-27' AND '2017-09-02'
GROUP BY SearchDate
SELECT DATE(DateTime) AS SearchDate, Total, NoMarkets, Complaints, Voicemails FROM
(SELECT COUNT() AS Total FROM CallRecords) CR
JOIN
(SELECT COUNT() AS NoMarkets FROM CallRecords WHERE NoMarket = 1) NM
ON CR.DateTime = NM.DateTime
JOIN
(SELECT COUNT() AS Complaints FROM CallRecords WHERE Complaint = 1) C
ON NM.DateTime = C.DateTime
JOIN
(SELECT COUNT() AS Voicemails FROM CallRecords WHERE Voicemail = 1) VM
ON C.DateTime = VM.DateTime
JOIN CallRecords CLR ON VM.DateTime=CLR.DateTime WHERE DATE(CLR.DateTime) >= '2017-08-27' AND DATE(CLR.DateTime) <= '2017-09-02'GROUP BY SearchDate;
This may Output correctly. 这可能正确输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.