【问题标题】:SQL aggregation by value of single columnSQL聚合按单列的值
【发布时间】:2021-12-25 23:33:59
【问题描述】:

假设我有一张这样的表:

Id url
1 11.22.33
2 11.22.33
3 domain.com
4 domain2.com
5 domain.com
6 10.100.15
7 domain3.com
8 172.100.15
9 172.100.15

在此表中,一些 IP 地址与一些域相关联,我们可以将它们视为单个 URL。 (例如,domain2.com、10.100.15、11.22.33 - 它是 domain2.com;172.100.15、domain3.com - domain3.com 等)。我的任务是我必须计算具有不同域的行并制作这样的表格:

url count
domain2 4
domain 2
domain3 2

我可以用几个查询来计算它们,例如:

SELECT COUNT(*) 
FROM table1
WHERE (table1.url = “10.100.15”
    OR table1.url = “11.22.33” OR table1.url = “domain2.com”)

手动制作这张桌子,但它并不酷。

如何在单个查询中完成?

PS:正如下面评论中提到的,通常的聚合可以通过一个简单的查询来完成:

SELECT url, count(*) 
FROM table1
WHERE GROUP BY url

但它只给了我这样的表格:

URL count
domain2 1
domain 2
11.22.33 2
10.100.15 1

还是我错过了什么?

【问题讨论】:

  • 您问题中的查询单个查询,不清楚您在问什么。
  • 如果没有以某种方式建立(例如通过自引用外键)IP 地址和域属于一起的规则,您将不得不使用CASE WHENWHERE 进行硬连线条件什么属于什么。我怎么能从数据中看到 - 而不是从你的文本中 - 什么属于什么?例如,以下域的所有前面的 ip 地址?
  • @marcothesane 你不能。假设您只知道硬编码条件。
  • 你可以像这样使用“in”操作符: where table1.url in( “10.100.15” ,“11.22.33” , domain2.com)
  • @vahidrobati 好的。然后什么?它只是让我只按 domain2 计数。

标签: sql group-by count case


【解决方案1】:

一种更优雅的方法是将关联存储在数据库中来实现:

WITH
-- your input ...
indata(Id,url) AS (
          SELECT 1,'11.22.33'
UNION ALL SELECT 2,'11.22.33'
UNION ALL SELECT 3,'domain.com'
UNION ALL SELECT 4,'domain2.com'
UNION ALL SELECT 5,'domain.com'
UNION ALL SELECT 6,'10.100.15'
UNION ALL SELECT 7,'domain3.com'
UNION ALL SELECT 8,'172.100.15'
UNION ALL SELECT 9,'172.100.15'
)
,
-- need an association table - which "url" belongs to which domain
assoc(dom,url) AS (
            SELECT 'domain2.com','10.100.15'
  UNION ALL SELECT 'domain2.com','11.22.33'
  UNION ALL SELECT 'domain3.com','172.100.15'
)
SELECT
  CASE 
    WHEN a.dom IS NULL THEN i.url
    ELSE a.dom
  END AS domain
, COUNT(*) AS counter
FROM indata AS i
LEFT
JOIN assoc  AS a USING(url)
GROUP BY domain
;

-- out
-- out    domain    | counter
-- out -------------+---------
-- out  domain2.com |       4                                                                                                                                                                             
-- out  domain3.com |       3
-- out  domain.com  |       2
-- out (3 rows)

【讨论】:

  • 一般来说,这是一个聪明的方法,虽然在我的情况下有点多余。无论如何,谢谢你!它可能很方便。
【解决方案2】:

您可以按CASE 表达式分组:

SELECT CASE 
         WHEN URL IN ('10.100.15', '11.22.33', 'domain2.com') THEN 'domain2.com'
         WHEN URL IN ('172.100.15', 'domain3.com') THEN 'domain3.com'
         ELSE URL
       END domain,
       COUNT(*) count
FROM tablename
GROUP BY domain;

请参阅demo

【讨论】:

  • 酷!谢谢!正是我需要的。
【解决方案3】:

你应该使用 group by function 并像这样编写你的代码:

选择网址,计数(*) 从表 1 其中 URL in('domain1','domain2') 按(URL)分组

它会起作用的!

【讨论】:

  • 不,不是。这让我可以按每个 URL 进行计数。我必须合并一些分配给 ONE 域的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 2018-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多