MySQL: как искать запись за каждый месяц между двумя датами в mysql, return 0 if null? с предложением group by date [duplicate]

Вам нужно использовать класс JsonNode и ObjectMapper из библиотеки jackson для извлечения узлов вашего дерева Json. Добавьте следующую зависимость в свой pom.xml, чтобы получить доступ к классам Джексона.

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
</dependency>

Вы должны попробовать следующий код: это

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

Class JsonNodeExtractor{

public void convertToJson(){


String filepath = "c:\\data.json";
ObjectMapper mapper = new ObjectMapper();
JsonNode node =  mapper.readTree(filepath);

// create a JsonNode for every root or subroot element in the Json String
JsonNode pageInfoRoot = node.path("pageInfo");

// Fetching elements under 'pageInfo'
String pageName =  pageInfoRoot.path("pageName").asText();
String pagePic = pageInfoRoot.path("pagePic").asText();

// Now fetching elements under posts
JsonNode  postsNode = node.path("posts");
String post_id = postsNode .path("post_id").asText();
String nameOfPersonWhoPosted = postsNode 
.path("nameOfPersonWhoPosted").asText();

}
}
4
задан O. Jones 2 July 2014 в 15:26
поделиться

3 ответа

Создание диапазона дат «на лету» и объединение этой таблицы против вас: -

SELECT sub1.sdate, COUNT(ORDERS.id) as Norders
FROM
(
    SELECT DATE_FORMAT(DATE_SUB(NOW(), INTERVAL units.i + tens.i * 10 + hundreds.i * 100 DAY), "%M %e") as sdate 
    FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)units
    CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)tens
    CROSS JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)hundreds
    WHERE DATE_SUB(NOW(), INTERVAL units.i + tens.i * 10 + hundreds.i * 100 DAY) BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
) sub1
LEFT OUTER JOIN ORDERS
ON sub1.sdate = DATE_FORMAT(ORDERS.date, "%M %e")
GROUP BY sub1.sdate

Это соответствует диапазонам дат до 1000 дней.

Обратите внимание, что

EDIT - в соответствии с запросом, чтобы получить количество заказов в месяц: -

SELECT aMonth, COUNT(ORDERS.id) as Norders
FROM
(
    SELECT DATE_FORMAT(DATE_SUB(NOW(), INTERVAL months.i MONTH), "%Y%m") as sdate, DATE_FORMAT(DATE_SUB(NOW(), INTERVAL months.i MONTH), "%M") as aMonth 
    FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11)months
    WHERE DATE_SUB(NOW(), INTERVAL months.i MONTH) BETWEEN DATE_SUB(NOW(), INTERVAL 12 MONTH) AND NOW()
) sub1
LEFT OUTER JOIN ORDERS
ON sub1.sdate = DATE_FORMAT(ORDERS.date, "%Y%m")
GROUP BY aMonth
3
ответ дан Kickstart 24 August 2018 в 02:51
поделиться

Сначала создайте таблицу календаря

SELECT coalesce(COUNT(O.*),0) as Norders, DATE_FORMAT(C.date, "%M %e") as sdate 
FROM Calendar C 
  LEFT JOIN ORDERS O ON C.date=O.date
WHERE O.date <= NOW() AND O.date >= NOW() - INTERVAL 1 MONTH 
GROUP BY DAY(date) 
ORDER BY date ASC;
1
ответ дан Community 24 August 2018 в 02:51
поделиться

Вам понадобится создать виртуальную (или физическую) таблицу, содержащую каждую дату в диапазоне.

Это можно сделать следующим образом, используя таблицу последовательностей.

SELECT mintime + INTERVAL seq.seq DAY AS orderdate
  FROM (
        SELECT CURDATE() - INTERVAL 1 MONTH AS mintime,
               CURDATE() AS maxtime
          FROM obs
       ) AS minmax
  JOIN seq_0_to_999999 AS seq ON seq.seq < TIMESTAMPDIFF(DAY,mintime,maxtime)

Затем вы присоединяете эту виртуальную таблицу к вашему запросу следующим образом.

SELECT IFNULL(orders.Norders,0) AS Norders, /* show zero instead of null*/
       DATE_FORMAT(alldates.orderdate, "%M %e") as sdate 
  FROM (
        SELECT mintime + INTERVAL seq.seq DAY AS orderdate
          FROM (
                SELECT CURDATE() - INTERVAL 1 MONTH AS mintime,
                       CURDATE() AS maxtime
                  FROM obs
               ) AS minmax
          JOIN seq_0_to_999999 AS seq 
                        ON seq.seq < TIMESTAMPDIFF(DAY,mintime,maxtime)
       ) AS alldates
  LEFT JOIN (
    SELECT COUNT(*) as Norders, DATE(date) AS orderdate
      FROM ORDERS 
    WHERE date <= NOW() 
      AND date >= NOW() - INTERVAL 1 MONTH 
    GROUP BY DAY(date) 
       ) AS orders ON alldates.orderdate = orders.orderdate
ORDER BY alldates.orderdate ASC

Обратите внимание, что вам нужно LEFT JOIN, чтобы строки в вашем результирующем наборе результатов сохранялись, даже если в вашей таблице ORDERS нет данных.

Где вы можете получить эту таблицу последовательности seq_0_to_999999 ]? Вы можете сделать это следующим образом.

DROP TABLE IF EXISTS seq_0_to_9;
CREATE TABLE seq_0_to_9 AS
   SELECT 0 AS seq UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
    UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9;

DROP VIEW IF EXISTS seq_0_to_999;
CREATE VIEW seq_0_to_999 AS (
SELECT (a.seq + 10 * (b.seq + 10 * c.seq)) AS seq
  FROM seq_0_to_9 a
  JOIN seq_0_to_9 b
  JOIN seq_0_to_9 c
);

DROP VIEW IF EXISTS seq_0_to_999999;
CREATE VIEW seq_0_to_999999 AS (
SELECT (a.seq + (1000 * b.seq)) AS seq
  FROM seq_0_to_999 a
  JOIN seq_0_to_999 b
);

Подробнее об этом можно узнать на http://www.plumislandmedia.net/mysql/filling-missing-data- sequence-cardinal-integers /

Если вы используете MariaDB версии 10+, эти таблицы последовательности встроены.

3
ответ дан O. Jones 24 August 2018 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: