如何使用SQL将相同的列值分组?

时间:2019-04-21 09:06:42

标签: mysql sql

首先,很抱歉,我的问题不清楚,但是很难用一句话来表达。 基本上,我有一个看起来像这样的表:

+-----------+-------------+
| BookName  | BookAuthor  |
+-----------+-------------+
| A         | Arthur      |
+-----------+-------------+
| A         | Will        |
+-----------+-------------+
| B         | Jack        |
+-----------+-------------+
| B         | Jack        |
+-----------+-------------+
| B         | Charles     |
+-----------+-------------+
| A         | Will        |
+-----------+-------------+
| A         | John        |
+-----------+-------------+

我正在寻找一个SQL查询,该查询可以将BookName和BookAuthor的相同值归为一组,以针对每个书名返回关联最多的书作者。

因此,按照我的示例,BookName“ A”将以“ Will”作为书作者,而BookName“ B”将具有“ Jack”。

我已经尝试过了: SELECT * FROM table GROUP BY BookName, BookAuthor HAVING BookName = "A",但我得到的结果是“亚瑟”。

任何帮助表示赞赏;非常感谢。

5 个答案:

答案 0 :(得分:1)

您可以按姓名和作者分组。在HAVING子句中,将计数与名称和作者在子查询中的另一个聚合进行比较,以获取计数,但这一次过滤名称,并将其限制为具有最大计数的(a)行。

SELECT t1.bookname,
       t1.bookauthor
       FROM elbat t1
       GROUP BY t1.bookname,
                t1.bookauthor
       HAVING count(*) = (SELECT count(*)
                                 FROM elbat t2
                                 WHERE t2.bookname = t1.bookname
                                 GROUP BY t2.bookname,
                                          t2.bookauthor
                                 ORDER BY count(*) DESC
                                 LIMIT 1);

db<>fiddle

虽然并没有打破关系。但是您没有提到是否需要以及在这种情况下规则如何。

答案 1 :(得分:0)

Select count(BookAuthor) as 'NoOfAuthAsso' from table group by BookName

这不会给您每本书的相关作者

答案 2 :(得分:0)

如果您想要输入的数量,可以使用count()并分组依据

select BookName, count(*)
from my_table  
group by BookName
order by count(*)

如果您想获得最多的条目,可以使用限制1

select BookName, count(*)
from my_table  
group by BookName
order by count(*)
limit 1

,对于每种书名中最常用的名称,您都可以尝试

select BookName, BookAuthor  ,  count(*)
from my_table  
group by BookNane, BookAuthor  
order by count(*)

答案 3 :(得分:0)

with cte_books
as
(
  select bookname,bookauthor
  ,row_number() over(partition by bookname,bookauthor order by bookname,bookauthor) as [NumOfBooks]
  from elbat
)

select a.bookname,a.bookauthor,a.NumOfBooks
from cte_books a
inner join (
             select bookname, max([NumOfBooks]) as [NumOfBooks] from cte_books group by bookname
           ) as b
on a.bookname = b.bookname
and a.[NumOfBooks] = b.[NumOfBooks]

答案 4 :(得分:0)

在统计信息中,这称为模式。在MySQL中执行此操作的一种相对简单的方法是进行两个级别的聚合:

select bookname,
       substring_index(group_concat(bookauthor order by cnt desc), ',', 1) as mode_author
from (select bookname, bookauthor, count(*) as cnt
      from t
      group by bookname, bookauthor
     ) b
group by bookname;

对此有一些细微差别。如果作者的名字可以有逗号,则需要使用其他分隔符。另外,如果作者列表超过了group_concat()的默认最大长度,则需要扩展该长度。

MySQL 8+当然通过支持窗口功能来简化此操作:

select bookname, bookauthor 
from (select bookname, bookauthor, count(*) as cnt,
             row_number() over (partition by bookname order by count(*) desc) as seqnum
      from t
      group by bookname, bookauthor
     ) b
where seqnum = 1;

如果您是领带,您不会说该怎么办。这样可以检索任意一名最佳作者。但是将row_number()更改为rank()会返回全部。