Mysql 如何显示GROUPBY语句中的所有行?

Mysql 如何显示GROUPBY语句中的所有行?,mysql,Mysql,如何在GROUPBY语句中显示所有行 以下是查询: SELECT year(feed_date) as date_year, month(feed_date) as date_month, count(*) as nb_item FROM table WHERE year(feed_date) = '2015' AND feed_title LIKE '%word%' AND source = '3' GROUP BY date_yea

如何在GROUPBY语句中显示所有行

以下是查询:

SELECT year(feed_date) as date_year, 
       month(feed_date) as date_month, 
       count(*) as nb_item 
FROM table 
WHERE year(feed_date) = '2015' AND
      feed_title LIKE '%word%' AND
      source = '3'
GROUP BY date_year, date_month
以下是输出:

-----------------
| 2015 |  7 | 5 |
| 2015 |  9 | 2 |
| 2015 | 10 | 4 |
| 2015 | 11 | 2 |
-----------------
以下是所需的输出:

-----------------
| 2015 |  1 | 0 |
| 2015 |  2 | 0 |
| 2015 |  3 | 0 |
| 2015 |  4 | 0 |
| 2015 |  5 | 0 |
| 2015 |  6 | 0 |
| 2015 |  7 | 5 |
| 2015 |  8 | 0 |
| 2015 |  9 | 2 |
| 2015 | 10 | 4 |
| 2015 | 11 | 2 |
| 2015 | 12 | 0 |
-----------------

通过标记
mysqli
我可以假设您正在使用PHP

因此,可以这样做:

 $year = '2015';
 $data = [];
 foreach(range(1, 12) AS $month) {
   $data[$month] = [
     'date_year'  => $year,
     'date_month' => $month,
     'nb_item'    => 0
   ];
 }

 $q = "SELECT 
       year(feed_date) as date_year, 
       month(feed_date) as date_month, 
       count(*) as nb_item 
       FROM table 
       WHERE year(feed_date) = '".$year."'
       GROUP BY date_year, date_month";
 $q = mysqli_query($q);
 while($record = mysqli_fetch_assoc($q)) {
   $data[$record['date_month']]['nb_item'] = $record['nb_item'];
 }

 $data = array_values($data);
 print_r($data);
或者使用mysql,这将是一个巨大的查询:

SELECT 
  year(table.feed_date) AS date_year, 
  month(table.feed_date) AS date_month, 
  COALESCE(count(*), 0) as nb_item 
FROM (
  SELECT 1 as month 
  UNION ALL SELECT 2 
  UNION ALL SELECT 3 
  UNION ALL SELECT 4 
  UNION ALL SELECT 5 
  UNION ALL SELECT 6 
  UNION ALL SELECT 7 
  UNION ALL SELECT 8 
  UNION ALL SELECT 9 
  UNION ALL SELECT 10 
  UNION ALL SELECT 11 
  UNION ALL SELECT 12
) months 
LEFT JOIN table ON (months.month = month(table.feed_date))
WHERE year(table.feed_date) = '2015' 
GROUP BY date_year, date_month;

通过标记
mysqli
我可以假设您正在使用PHP

因此,可以这样做:

 $year = '2015';
 $data = [];
 foreach(range(1, 12) AS $month) {
   $data[$month] = [
     'date_year'  => $year,
     'date_month' => $month,
     'nb_item'    => 0
   ];
 }

 $q = "SELECT 
       year(feed_date) as date_year, 
       month(feed_date) as date_month, 
       count(*) as nb_item 
       FROM table 
       WHERE year(feed_date) = '".$year."'
       GROUP BY date_year, date_month";
 $q = mysqli_query($q);
 while($record = mysqli_fetch_assoc($q)) {
   $data[$record['date_month']]['nb_item'] = $record['nb_item'];
 }

 $data = array_values($data);
 print_r($data);
或者使用mysql,这将是一个巨大的查询:

SELECT 
  year(table.feed_date) AS date_year, 
  month(table.feed_date) AS date_month, 
  COALESCE(count(*), 0) as nb_item 
FROM (
  SELECT 1 as month 
  UNION ALL SELECT 2 
  UNION ALL SELECT 3 
  UNION ALL SELECT 4 
  UNION ALL SELECT 5 
  UNION ALL SELECT 6 
  UNION ALL SELECT 7 
  UNION ALL SELECT 8 
  UNION ALL SELECT 9 
  UNION ALL SELECT 10 
  UNION ALL SELECT 11 
  UNION ALL SELECT 12
) months 
LEFT JOIN table ON (months.month = month(table.feed_date))
WHERE year(table.feed_date) = '2015' 
GROUP BY date_year, date_month;

您需要一个包含左联接的所有年-月组合的表。您可以通过交叉连接所有年份和月份来动态创建它:

SELECT y.date_year, m.date_month, count(*) as nb_item 
FROM (
    SELECT 1 as date_month UNION ALL
    SELECT 2 UNION ALL
    SELECT 3 UNION ALL
    SELECT 4 UNION ALL
    SELECT 5 UNION ALL
    SELECT 6 UNION ALL
    SELECT 7 UNION ALL
    SELECT 8 UNION ALL
    SELECT 9 UNION ALL
    SELECT 10 UNION ALL
    SELECT 11 UNION ALL
    SELECT 12
) m
CROSS JOIN (
    SELECT 2015 as date_year
) y
LEFT JOIN `table` t 
    ON  year(t.feed_date)  = y.date_year
    AND month(t.feed_date) = m.date_month
    AND t.feed_title LIKE '%word%'
    AND t.source = '3'
GROUP BY y.date_year, m.date_month
如果您有一个带有序列号的辅助表,则可以将查询缩短为:

SELECT y.seq as date_year, m.seq as date_month, count(*) as nb_item 
FROM sequences y
CROSS JOIN sequences m
LEFT JOIN `table` t 
    ON  year(t.feed_date)  = y.date_year
    AND month(t.feed_date) = m.date_month
    AND t.feed_title LIKE '%word%'
    AND t.source = '3'
WHERE y.seq IN (2015)
  AND m.seq <= 12
GROUP BY y.seq, m.seq
选择y.seq作为日期年,m.seq作为日期月,计数(*)作为nb项目
从序列y
交叉连接序列
左JOIN`table`t
年份(t.feed_date)=y.date_年
月份(t.feed_date)=m.date_月
和t.feed_标题,如“%word%”
而t.source='3'
其中y.seq在(2015年)

和m.seq您需要一个包含左联接的所有年-月组合的表。您可以通过交叉连接所有年份和月份来动态创建它:

SELECT y.date_year, m.date_month, count(*) as nb_item 
FROM (
    SELECT 1 as date_month UNION ALL
    SELECT 2 UNION ALL
    SELECT 3 UNION ALL
    SELECT 4 UNION ALL
    SELECT 5 UNION ALL
    SELECT 6 UNION ALL
    SELECT 7 UNION ALL
    SELECT 8 UNION ALL
    SELECT 9 UNION ALL
    SELECT 10 UNION ALL
    SELECT 11 UNION ALL
    SELECT 12
) m
CROSS JOIN (
    SELECT 2015 as date_year
) y
LEFT JOIN `table` t 
    ON  year(t.feed_date)  = y.date_year
    AND month(t.feed_date) = m.date_month
    AND t.feed_title LIKE '%word%'
    AND t.source = '3'
GROUP BY y.date_year, m.date_month
如果您有一个带有序列号的辅助表,则可以将查询缩短为:

SELECT y.seq as date_year, m.seq as date_month, count(*) as nb_item 
FROM sequences y
CROSS JOIN sequences m
LEFT JOIN `table` t 
    ON  year(t.feed_date)  = y.date_year
    AND month(t.feed_date) = m.date_month
    AND t.feed_title LIKE '%word%'
    AND t.source = '3'
WHERE y.seq IN (2015)
  AND m.seq <= 12
GROUP BY y.seq, m.seq
选择y.seq作为日期年,m.seq作为日期月,计数(*)作为nb项目
从序列y
交叉连接序列
左JOIN`table`t
年份(t.feed_date)=y.date_年
月份(t.feed_date)=m.date_月
和t.feed_标题,如“%word%”
而t.source='3'
其中y.seq在(2015年)

和m.seq您可以使用从表中获取所有现有年份和月份的子查询来连接所选数据

SELECT t1.date_year, t1.date_monthmonth, IFNULL(t2.nb_item, 0) AS nb_item
FROM (SELECT DISTINCT YEAR(feed_date) AS date_year, MONTH(feed_date) AS date_month 
      FROM table) AS t1
LEFT JOIN (
    SELECT year(feed_date) as date_year, 
           month(feed_date) as date_month, 
           count(*) as nb_item 
    FROM table 
    WHERE year(feed_date) = '2015' AND
          feed_title LIKE '%word%' AND
          source = '3'
    GROUP BY date_year, date_month) AS t2
ON t1.date_year = t2.date_year AND t1.date_month = t2.date_month
ORDER BY t1.date_year, t1.date_month

您可以使用从表中获取所有现有年份和月份的子查询联接所选数据

SELECT t1.date_year, t1.date_monthmonth, IFNULL(t2.nb_item, 0) AS nb_item
FROM (SELECT DISTINCT YEAR(feed_date) AS date_year, MONTH(feed_date) AS date_month 
      FROM table) AS t1
LEFT JOIN (
    SELECT year(feed_date) as date_year, 
           month(feed_date) as date_month, 
           count(*) as nb_item 
    FROM table 
    WHERE year(feed_date) = '2015' AND
          feed_title LIKE '%word%' AND
          source = '3'
    GROUP BY date_year, date_month) AS t2
ON t1.date_year = t2.date_year AND t1.date_month = t2.date_month
ORDER BY t1.date_year, t1.date_month


您确定GROUPBY之后没有Having子句吗?这是一个明显但必要的问题:所有这些行实际上都存在于DB中吗,或者您希望它能生成用于此查询的结果吗?我想原始表中可能没有几个月。@ADyson不是很明显,但非常必要处理应用程序代码中缺少结果的逻辑(如您包含mysqli标记所示),您确定,GROUPBY后面没有Having子句?这是一个明显但必要的问题:所有这些行实际上都存在于DB中吗,或者您希望它能生成用于此查询的结果吗?我想原始表中可能没有几个月。@ADyson不是很明显,但非常有必要处理应用程序代码中缺少结果的逻辑(如您包含的mysqli标记所示)你写得比我快:谢谢你的回答,但年份也是一个变量,而不是一个常数。所以,我不知道如何调整CROSS-JOIN语句中的查询…@Guillaume在示例中MySQL的年份是常量,就像您的问题一样。您可以使用
SELECT?作为日期年
选择$year作为日期年
@PaulSpiegel我使用的是一系列年,而不是一年。对不起,如果我的问题不够清楚的话。@Guillaume对于某个范围,我肯定会使用序列表,在WHERE子句中写入类似于2013年到2015年之间的
y.seq的内容。你写得比我快:谢谢你的回答,但年份也是一个变量,而不是常量。所以,我不知道如何调整CROSS-JOIN语句中的查询…@Guillaume在示例中MySQL的年份是常量,就像您的问题一样。您可以使用
SELECT?作为日期年
选择$year作为日期年
@PaulSpiegel我使用的是一系列年,而不是一年。很抱歉如果我的问题不够清楚。@Guillaume对于某个范围,我肯定会使用一个序列表,并在WHERE子句中写入类似于2013年到2015年之间的
y.seq的内容。我得到以下错误消息:#1054-字段列表中的未知列't2.count',我将
date\u monthmonth
更正为
date\u month
MONT(feed_date)
月(feed_date)
。但仍然不起作用…这应该是
nb_项
我收到了这个错误消息:#1054-字段列表中的未知列“t2.count”我更正了
日期月
日期月
月(feed_date)
月(feed_date)
。但仍然不起作用…这应该是
nb\u项