Mil*_*uri 4 sql eloquent laravel-query-builder
我在 SQL 中有这样的产品表:
productID Type Amount
1046 1 4
1046 1 5
1046 2 10
1047 1 5
1047 2 3
Run Code Online (Sandbox Code Playgroud)
如何进行查询,输出如下:
productID Type TotalTypeAmount TotalPerProductID
1046 1 9 19
1046 2 10 19
1047 1 5 8
1047 2 3 8
Run Code Online (Sandbox Code Playgroud)
Cai*_*ard 13
更紧凑/专业的方式也应该更快,因为它不需要加入:
\n\nSELECT \n productID,\n Type,\n SUM(Amount) AS TotalTypeAmount,\n SUM(SUM(Amount)) OVER (PARTITION BY productID) as TotalPerProduct\nFROM \n Product\nGROUP BY \n productID,Type\nRun Code Online (Sandbox Code Playgroud)\n\nhttp://sqlfiddle.com/#!6/ca308/4
\n\nSUM(amount)是每个金额的总和,productid,type即如果您刚刚执行 GROUP BY,您将得到的总和,因此您将有多个不同的总和,productid因为它们被分解为type子组。SUM(SUM(amount)) PARTITION BY(productid)是“仅按productid分组的sum_per_productid_and_type的总和”
假设我们有更简单的查询:
\n\nSELECT \n productID,\n Type,\n SUM(Amount) AS TotalTypeAmount\nFROM \n Product\nGROUP BY \n productID,Type\nRun Code Online (Sandbox Code Playgroud)\n\n这可能会产生如下结果:
\n\nid1, type1, 100\nid1, type2, 200\nid2, type1, 300\nid2, type2, 400\nRun Code Online (Sandbox Code Playgroud)\n\n我们可以看到,所有 id2 的总数id1为300,所有 id2 的总数为700。我们可以引入一个窗口函数,仅通过productid对所有数据进行求和,并且它会产生重复求和的结果,而不是导致行数缩小,即:
id1, type1, 100, 300\nid1, type2, 200, 300\nid2, type1, 300, 700\nid2, type2, 400, 700\nRun Code Online (Sandbox Code Playgroud)\n\n这是因为窗口函数会进行分组/求和,然后将结果应用于每一行。
\n\n重要的是要理解,窗口操作是在分组和求和完成之后执行的,但在我们在 SELECT 中为列指定任何别名之前执行。如果在窗口函数运行之前已经分配了列名,那么我们可以SUM(TotalTypeAmount)说SUM(SUM(Amount)):
SELECT \n productID,\n Type,\n SUM(Amount) AS TotalTypeAmount,\n SUM(TotalTypeAmount) OVER (PARTITION BY productID) as TotalPerProduct\nFROM \n Product\nGROUP BY \n productID,Type\nRun Code Online (Sandbox Code Playgroud)\n\n但这是一个语法错误,因为我们无法在定义它的同一个 SELECT 中引用 TotalTypeAmount。不过,我们可以通过使用子查询来实现这一点:
\n\nSELECT\n x.productID,\n x.Type,\n x.TotalTypeAmount, --here we use it after it has been defined in the subquery\n SUM(x.TotalTypeAmount) OVER (PARTITION BY x.productID) as TotalPerProduct\nFROM\n(\n SELECT \n productID,\n Type,\n SUM(Amount) AS TotalTypeAmount --here we define it\n FROM \n Product\n GROUP BY \n productID,Type\n) x\nRun Code Online (Sandbox Code Playgroud)\n\n但它比需要的更复杂。
\n\n从本质上讲,虽然看起来很奇怪,但我们只需要记住,当我们看到:
\n\nSUM(sum(\xe2\x80\xa6)) OVER(PARTITION BY \xe2\x80\xa6)\n\xe2\x80\xa6\ngroup by \xe2\x80\xa6 \nRun Code Online (Sandbox Code Playgroud)\n\nsum(amount)是“GROUP BY 所做的总和”,并且SUM(\xe2\x80\xa6) OVER(\xe2\x80\xa6)是“窗口函数完成的总和”我们必须重复一遍,SUM(SUM(amount))因为在运行窗口函数时,group by 完成的总和(即我们想要总计的东西)没有自己的名称 - 它只是被称为SUM(amount)
| 归档时间: |
|
| 查看次数: |
11182 次 |
| 最近记录: |