【问题标题】:Count values over m/n connected tables in SQL在 SQL 中计算 m/n 连接表上的值
【发布时间】:2014-03-05 18:38:50
【问题描述】:

我有四个表,想知道某个名称有多少个位置和下载量。 nameslocations 通过 names_locations 表连接

这是我的桌子:

表“names

ID | name
=========
 1 | foo
 2 | bar
 3 | zoo
 4 | luu

表“locations

ID | location
=============
 1 | Hamburg
 2 | New York
 3 | Singapore
 4 | Tokio

表格“names_locations

ID | location_id | name_id
==========================
 1 | 1           | 1
 2 | 1           | 2
 3 | 2           | 2
 4 | 3           | 3
 5 | 1           | 2

表格“downloads

ID | name_id | timestamp
=========================
 1 | 1       | 1394041682
 2 | 4       | 1394041356
 3 | 1       | 1394041573
 4 | 3       | 1394041981
 5 | 1       | 1394041683

结果应该是:

ID | name | locations | downloads
=================================
 1 | foo  | 1         | 3
 2 | bar  | 3         | 0
 3 | zoo  | 1         | 1
 4 | luu  | 0         | 1

这是我的尝试(没有下载栏):

SELECT names.*, 
       Count(names_locations.location_id) AS location 
FROM   names 
       LEFT JOIN names_locations 
              ON names.ID = names_locations.name_id 
GROUP  BY names.ID 

【问题讨论】:

  • 请更新您的问题并尝试解决此问题。
  • @AgRizzo 是的,这是我之前的问题
  • 我无法理解 id=1 的位置数是 1,而 id=2 的位置数是 3 .. 如果我们考虑不同的位置,id=2 的位置数不应该是 2 吗?
  • @Nishant 在 names_locations 表中还有第三个 id=2

标签: mysql sql


【解决方案1】:

我认为这会奏效。

SELECT n.id,
       n.name,
       COUNT(DISTINCT l.id) AS locations,
       COUNT(DISTINCT d.id) AS downloads
FROM names n LEFT JOIN names_location nl
  ON n.id = nl.name_id
LEFT JOIN downloads dl
  ON n.id = dl.name_id
LEFT JOIN locations l
  ON l.id = nl.location_id
GROUP BY n.id, n.name

【讨论】:

  • 是的。不过我忘记了区别,你明白了。
  • 这使得位置计数为 2 为 id = 2
  • 我确实假设他们想要匹配不同的位置,并且可能不应该匹配,因为他们在所需的输出中显示 3。将 COUNT(DISTINCT l.id) 替换为 COUNT(DISTINCT nl.id) 会更改计数以匹配其示例输出。
【解决方案2】:

所有这些似乎都有效。这是另一个。

SELECT 
  a.ID,
  a.name,
  COUNT(c.location) AS locations,
  COUNT(d.timestamp) AS downloads 
FROM names AS a
  LEFT JOIN names_locations AS b on a.ID=b.name_id
  LEFT JOIN locations AS c ON b.location_id=c.ID
  LEFT JOIN downloads AS d ON a.ID=d.name_id
GROUP BY a.name

【讨论】:

  • +-----+------+-----------+-----------+ |身份证 |姓名 |地点 |下载 | +--------+------+------------+------------+ | 2 |酒吧 | 3 | 0 | | 1 |富 | 3 | 3 | | 4 |卢 | 0 | 1 | | 3 |动物园 | 1 | 1 | +------+------+-----------+------------+ 4 行(0.00 秒).. i运行它并得到如上的输出,这是预期的输出吗..
  • 是的,正如我在@Alden 的回答中评论的那样,我忘记了获得正确结果所需的DISTINCT() 部分。因此,我赞成他的回答。简单地用另一个人的答案更新我的答案是违反我的原则的
  • 我不认为它是由于不同.. 因为 id=2 的位置计数是 3.. 并且它有一个重复的 location_id。
  • 哦,你是对的……嗯……那是……出乎意料。也许他想要ID的总和? :p
  • 发布了一个解决方案,可以提供所需的 o/p
【解决方案3】:
SELECT
  t.id,t.n AS name,
  count(location_id) AS locations,
  t.downloads
FROM names_location 
RIGHT JOIN 
 (SELECT 
    names.id AS id,
    names.name AS n, 
    count(timestamp) AS downloads 
  FROM names
    LEFT JOIN downloads ON names.id = downloads.name_id
    GROUP BY id) AS t 
ON t.id = names_location.name_id
GROUP BY t.id

输出:

+------+------+-----------+-----------+
| id   | name | locations | downloads |
+------+------+-----------+-----------+
|    1 | foo  |         1 |         3 |
|    2 | bar  |         3 |         0 |
|    3 | zoo  |         1 |         1 |
|    4 | luu  |         0 |         1 |
+------+------+-----------+-----------+
4 rows in set (0.00 sec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多