简体   繁体   English

SQL组合多个SELECT语句

[英]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表中有一堆乱七八糟的列,其名称包括ComplaintVoicemail ,每个列都对一个电话进行分类。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM