【问题标题】:Normalize data in SQL query规范化 SQL 查询中的数据
【发布时间】:2014-10-21 01:58:23
【问题描述】:

我有一个 SQL 查询 A(有关详细信息,请参阅下文),它返回如下表:

cluster  brand  amount
0         bos     600
0         phi     300
0         har     100
1         pro    2500
1         wal    1500
1         ash    1000
2         dil    4200
2         sor     500
2         van     300
...

但是,我想显示的不是数量,而是该数量与该集群中总量相比的比例,如下表所示:

cluster  brand  amount
0         bos    0.60
0         phi    0.30
0         har    0.10
1         pro    0.50
1         wal    0.30
1         ash    0.20
2         dil    0.84
2         sor    0.10
2         van    0.06
...

我应该如何更改我的 SQL 以便我可以访问一个集群中所有金额的总和,并且同一集群仍然有多个行?

** 详情**

SQL 服务器:MySQL,通过 python-MySQL 连接器连接。

用于生成第一个表的当前 SQL 查询:

SELECT c.cluster, brand, COUNT(o.id) AS brand_amount
FROM nyon_all.clustering AS c 
LEFT JOIN nyon_all.persons AS p ON c.pid = p.id 
LEFT JOIN nyon_all.orders AS o ON p.id = o.pid 
LEFT JOIN nyon_all.articles AS a ON o.aid = a.id 
LEFT JOIN nyon_all.brands AS ab ON a.brand_id = ab.id 
WHERE c.cluster_round = 'Org_2014-08-27_10:45:35'
GROUP BY cluster, brand 
HAVING brand_amount > 100
ORDER BY c.cluster ASC, brand_amount DESC;

orders(主键id)链接persons(外键pid)和articles(外键aid)。 Articles有某个品牌(外键brand_id),与表brands中的一个名字相关。

可以使用以下 SQL 查询检索每个集群的文章总数:

SELECT c.cluster, COUNT(o.pid) AS amount
FROM nyon_all.clustering AS c 
LEFT JOIN nyon_all.persons AS p ON c.pid = p.id 
LEFT JOIN nyon_all.orders AS o ON p.id = o.pid 
WHERE c.cluster_round = 'Org_2014-08-27_10:45:35'
GROUP BY cluster
ORDER BY c.cluster ASC, amount DESC;

结果:

cluster amount
0        1000
1        5000
2        5000

但是,我似乎无法组合这两个 SQL 查询。

【问题讨论】:

  • 数据在 TABLES 中被规范化,而不是在 SQL 查询中! :)

标签: mysql sql normalization


【解决方案1】:

您可以对子查询进行连接,按集群对数量求和

select t1.cluster, amount / sumAmount 
from Table1 t1
join (select cluster, sum(amount) as sumAmount
      from Table1
      group by cluster)s
on t1.cluster = s.cluster

SqlFiddle

编辑

SELECT 
    c.cluster, 
    brand, 
    COUNT(o.id) / coalesce(s.sumBrandAmount, 0) AS brand_amount -- of course it would be nice to check for dividing by 0
FROM nyon_all.clustering AS c 
LEFT JOIN nyon_all.persons AS p ON c.pid = p.id 
LEFT JOIN nyon_all.orders AS o ON p.id = o.pid 
LEFT JOIN nyon_all.articles AS a ON o.aid = a.id 
LEFT JOIN nyon_all.brands AS ab ON a.brand_id = ab.id 
LEFT JOIN (select c1.id, count(o1.id) as sumBrandAmount
           from nyon_all.clustering c1
           left join nyon_all.persons p1 on p1.id = c1.pid
           left join nony_all.orders as o1 on o1.id = p1.id
           --maybe some where clause as in your main query
           group by c1.id) s
                               ON s.id = c.id
WHERE c.cluster_round = 'Org_2014-08-27_10:45:35'
GROUP BY cluster, brand 
HAVING brand_amount > 100
ORDER BY c.cluster ASC, brand_amount DESC;

【讨论】:

  • 感谢您的回答,但我不明白。我应该用我的大查询替换 Table1 吗?如果我尝试这样做,我会收到错误代码 1054:“字段列表”中的未知列“金额”。我不熟悉 SqlFiddle。该链接向我显示了两个空方块。我该怎么办?
  • @physicalattraction 似乎 SqlFiddle 存在一些问题(并不总是有效)...我会尝试用您的查询编辑我的答案。
  • @physicalattraction 请参阅编辑后的答案。当然,为了让事情更容易阅读,您可以根据问题的查询创建一个视图,并使用它而不是重写所有...
猜你喜欢
  • 2017-05-09
  • 2020-08-14
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 2011-10-07
  • 2012-12-25
  • 2011-04-17
相关资源
最近更新 更多