英文:
Add Total Row in SQL Query (Pivot)
问题
这是查询部分,不要翻译:
SELECT
*,
ISNULL([In Use], 0.) + ISNULL([Used - In Store], 0.) + ISNULL([In Store], 0.) + ISNULL([New - In Store], 0.) + ISNULL([Damaged], 0.) + ISNULL([Faulty], 0.) AS TOTAL
FROM
(
SELECT
max("product"."COMPONENTNAME") AS "Product",
max("state"."DISPLAYSTATE") AS "Asset State",
count("resource"."RESOURCENAME") AS "Asset Count"
FROM
"Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID" = "product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID" = "state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID" = "rOwner"."RESOURCEID"
LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID" = "rToAsset"."RESOURCEOWNERID"
LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID" = "sdUser"."USERID"
LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID" = "aaaUser"."USER_ID"
WHERE
product.COMPONENTNAME LIKE ('Thinkpad%')
GROUP BY
"product"."COMPONENTNAME",
"state"."DISPLAYSTATE"
) d pivot (
sum("Asset Count") for "Asset State" in (
[In Use], [Used - In Store], [In Store],
[New - In Store], [Damaged], [Faulty]
)
) piv
如果您需要进一步的翻译或帮助,请告诉我。
英文:
We are using a asset management software and unfortunatly unable to get the proper support in DIY implementation. I was looking to get an asset report (Laptop Count based on model and state).
With the help of google I manage to create a pivot for the required report. Now, I am stuck with the last part of the task. which is to get a total row for asset state e.g. (In - Store, New - In Store) at the bottom.
This is the Query and I am unable to understand how to add the total row.
SELECT
*,
ISNULL([In Use], 0.) + ISNULL([Used - In Store], 0.) + ISNULL([In Store], 0.) + ISNULL([New - In Store], 0.) + ISNULL([Damaged], 0.) + ISNULL([Faulty], 0.) AS TOTAL
FROM
(
SELECT
max("product"."COMPONENTNAME") AS "Product",
max("state"."DISPLAYSTATE") AS "Asset State",
count("resource"."RESOURCENAME") AS "Asset Count"
FROM
"Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID" = "product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID" = "state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID" = "rOwner"."RESOURCEID"
LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID" = "rToAsset"."RESOURCEOWNERID"
LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID" = "sdUser"."USERID"
LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID" = "aaaUser"."USER_ID"
WHERE
product.COMPONENTNAME LIKE ('Thinkpad%')
GROUP BY
"product"."COMPONENTNAME",
"state"."DISPLAYSTATE"
) d pivot (
sum("Asset Count") for "Asset State" in (
[In Use], [Used - In Store], [In Store],
[New - In Store], [Damaged], [Faulty]
)
) piv
答案1
得分: 1
以下是代码部分的翻译:
-
在维度中自动生成总计,您可以使用
GROUP BY ... WITH CUBE
。这将添加一个总计行,并且还会消除显式计算总计列的需求。 -
ISNULL()
用于为分组的产品和状态名称分配标签,否则将为null。[Total]
也已添加到数据透视列表,并从最终选择列表中删除。如果您希望将空值替换为零,可能需要编辑选择列表以添加ISNULL()
函数(例如,ISNULL([In Use], 0) AS [In Use], ...
)。 -
结果:
产品 | 在使用 | 在库存中使用 | 存储中 | 新库存中使用 | 损坏 | 故障 | 总计 |
---|---|---|---|---|---|---|---|
Thinkpad 101 | 2 | 2 | 3 | 1 | 1 | 1 | 10 |
Thinkpad 102 | 1 | null | null | null | null | null | 1 |
Thinkpad 103 | null | null | null | null | 1 | 1 | 2 |
总计: | 3 | 2 | 3 | 1 | 2 | 2 | 13 |
-
您还可以使用
GROUP BY ... WITH ROLLUP
为行编写类似的结果,并使用"条件聚合"来定义列,作为数据透视的替代。 -
"条件聚合"是一种非正式术语,用于将聚合函数如
SUM()
或COUNT()
与CASE
表达式一起使用。如果条件为真,THEN
子句提供要聚合的数据。当条件为假时,隐式的ELSE null
值将被忽略。 -
结果:
产品 | 在使用 | 在库存中使用 | 存储中 | 新库存中使用 | 损坏 | 故障 | 总计 |
---|---|---|---|---|---|---|---|
Thinkpad 101 | 2 | 2 | 3 | 1 | 1 | 1 | 10 |
Thinkpad 102 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
Thinkpad 103 | 0 | 0 | 0 | 0 | 1 | 1 | 2 |
总计 | 3 | 2 | 3 | 1 | 2 | 2 | 13 |
希望这对您有所帮助。
英文:
You can use GROUP BY ... WITH CUBE
to automatically generate totals in both dimensions. This will add a totals row and will also eliminate the need to explicitly calculate the totals column.
SELECT piv.*
FROM (
SELECT
ISNULL(product."COMPONENTNAME", 'Totals:') AS "Product",
ISNULL(state."DISPLAYSTATE", 'TOTAL') AS "Asset State",
count(resource."RESOURCENAME") AS "Asset Count"
FROM
"Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID" = "product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID" = "state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID" = "rOwner"."RESOURCEID"
LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID" = "rToAsset"."RESOURCEOWNERID"
LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID" = "sdUser"."USERID"
LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID" = "aaaUser"."USER_ID"
WHERE
product.COMPONENTNAME LIKE ('Thinkpad%')
GROUP BY
product."COMPONENTNAME",
state."DISPLAYSTATE"
WITH CUBE
) d
pivot (
sum("Asset Count") for "Asset State" in (
[In Use], [Used - In Store], [In Store],
[New - In Store], [Damaged], [Faulty],
[TOTAL])
) piv
ORDER BY
CASE WHEN piv.Product = 'Totals:' THEN 2 ELSE 1 END,
piv.Product
ISNULL()
is used to assign labels to the grouped product and status names, which would otherwise be null. [Total]
has also been added to the pivot list and removed from the final select list. You may need to edit the select list to add ISNULL()
functions if you want to replace null values with zeros. (E.g., ISNULL([In Use], 0) AS [In Use], ...
)
Results:
Product | In Use | Used - In Store | In Store | New - In Store | Damaged | Faulty | TOTAL |
---|---|---|---|---|---|---|---|
Thinkpad 101 | 2 | 2 | 3 | 1 | 1 | 1 | 10 |
Thinkpad 102 | 1 | null | null | null | null | null | 1 |
Thinkpad 103 | null | null | null | null | 1 | 1 | 2 |
Totals: | 3 | 2 | 3 | 1 | 2 | 2 | 13 |
You can also code a similar result using GROUP BY ... WITH ROLLUP
for the rows together with "conditional aggregation" to define the columns as a replacement for the pivot.
SELECT
ISNULL(product.COMPONENTNAME, 'Total') AS Product,
COUNT(CASE WHEN state.DISPLAYSTATE = 'In Use' THEN 1 END) AS [In Use],
COUNT(CASE WHEN state.DISPLAYSTATE = 'Used - In Store' THEN 1 END) AS [Used - In Store],
COUNT(CASE WHEN state.DISPLAYSTATE = 'In Store' THEN 1 END) AS [In Store],
COUNT(CASE WHEN state.DISPLAYSTATE = 'New - In Store' THEN 1 END) AS [New - In Store],
COUNT(CASE WHEN state.DISPLAYSTATE = 'Damaged' THEN 1 END) AS [Damaged],
COUNT(CASE WHEN state.DISPLAYSTATE = 'Faulty' THEN 1 END) AS [Faulty],
COUNT(*) AS TOTAL
FROM
"Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID" = "product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID" = "state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID" = "rOwner"."RESOURCEID"
LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID" = "rToAsset"."RESOURCEOWNERID"
LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID" = "sdUser"."USERID"
LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID" = "aaaUser"."USER_ID"
WHERE
product.COMPONENTNAME LIKE ('Thinkpad%')
GROUP BY product.COMPONENTNAME WITH ROLLUP
ORDER BY
CASE WHEN GROUPING(product.COMPONENTNAME) = 0 THEN 1 ELSE 2 END,
product.COMPONENTNAME
"Conditional aggregation" is an informal term for usieng aggregation functions like SUM()
or COUNT()
together with a CASE
expression. If the condition is true, the THEN
clause provides the data to be aggregated. When false, the implicit ELSE null
value is ignored.
Results:
Product | In Use | Used - In Store | In Store | New - In Store | Damaged | Faulty | TOTAL |
---|---|---|---|---|---|---|---|
Thinkpad 101 | 2 | 2 | 3 | 1 | 1 | 1 | 10 |
Thinkpad 102 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
Thinkpad 103 | 0 | 0 | 0 | 0 | 1 | 1 | 2 |
Total | 3 | 2 | 3 | 1 | 2 | 2 | 13 |
See this db<>fiddle for examples of both using simplified test data.
答案2
得分: 0
您可以使用'UNION'来将两个查询连接在一起,以获取总行数;它可能是这样的:
SELECT *, ISNULL([In Use], 0.) + ISNULL([Used - In Store], 0.) + ISNULL([In Store], 0.) + ISNULL([New - In Store], 0.) + ISNULL([Damaged], 0.) + ISNULL([Faulty], 0.) AS TOTAL
FROM (
SELECT max("product"."COMPONENTNAME") AS "Product", max("state"."DISPLAYSTATE") AS "Asset State", count("resource"."RESOURCENAME") AS "Asset Count" FROM "Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID"="product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID"="state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID"="rOwner"."RESOURCEID" LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID"="rToAsset"."RESOURCEOWNERID" LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID"="sdUser"."USERID" LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID"="aaaUser"."USER_ID"
WHERE product.COMPONENTNAME LIKE 'ThinkPad %'
GROUP BY "product"."COMPONENTNAME","state"."DISPLAYSTATE")d
UNION
SELECT "Totals:", ISNULL([In Use], 0.) + ISNULL([Used - In Store], 0.) + ISNULL([In Store], 0.) + ISNULL([New - In Store], 0.) + ISNULL([Damaged], 0.) + ISNULL([Faulty], 0.) AS TOTAL
FROM (
SELECT max("product"."COMPONENTNAME") AS "Product", max("state"."DISPLAYSTATE") AS "Asset State", count("resource"."RESOURCENAME") AS "Asset Count" FROM "Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID"="product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID"="state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID"="rOwner"."RESOURCEID" LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID"="rToAsset"."RESOURCEOWNERID" LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID"="sdUser"."USERID" LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID"="aaaUser"."USER_ID"
WHERE product.COMPONENTNAME LIKE 'ThinkPad %'
GROUP BY "state"."DISPLAYSTATE")d
<details>
<summary>英文:</summary>
You could use 'UNION' to join two queries together to give you a total row; it'd be something like:
SELECT *, ISNULL([In Use], 0.) + ISNULL([Used - In Store], 0.) + ISNULL([In Store], 0.) + ISNULL([New - In Store], 0.) + ISNULL([Damaged], 0.) + ISNULL([Faulty], 0.) AS TOTAL
FROM (
SELECT max("product"."COMPONENTNAME") AS "Product", max("state"."DISPLAYSTATE") AS "Asset State", count("resource"."RESOURCENAME") AS "Asset Count" FROM "Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID"="product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID"="state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID"="rOwner"."RESOURCEID" LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID"="rToAsset"."RESOURCEOWNERID" LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID"="sdUser"."USERID" LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID"="aaaUser"."USER_ID"
WHERE product.COMPONENTNAME LIKE 'ThinkPad %'
GROUP BY "product"."COMPONENTNAME","state"."DISPLAYSTATE")d
UNION
SELECT "Totals:", ISNULL([In Use], 0.) + ISNULL([Used - In Store], 0.) + ISNULL([In Store], 0.) + ISNULL([New - In Store], 0.) + ISNULL([Damaged], 0.) + ISNULL([Faulty], 0.) AS TOTAL
FROM (
SELECT max("product"."COMPONENTNAME") AS "Product", max("state"."DISPLAYSTATE") AS "Asset State", count("resource"."RESOURCENAME") AS "Asset Count" FROM "Resources" "resource"
LEFT JOIN "ComponentDefinition" "product" ON "resource"."COMPONENTID"="product"."COMPONENTID"
LEFT JOIN "ResourceState" "state" ON "resource"."RESOURCESTATEID"="state"."RESOURCESTATEID"
LEFT JOIN "ResourceOwner" "rOwner" ON "resource"."RESOURCEID"="rOwner"."RESOURCEID" LEFT JOIN "ResourceAssociation" "rToAsset" ON "rOwner"."RESOURCEOWNERID"="rToAsset"."RESOURCEOWNERID" LEFT JOIN "SDUser" "sdUser" ON "rOwner"."USERID"="sdUser"."USERID" LEFT JOIN "AaaUser" "aaaUser" ON "sdUser"."USERID"="aaaUser"."USER_ID"
WHERE product.COMPONENTNAME LIKE 'ThinkPad %'
GROUP BY "state"."DISPLAYSTATE")d
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论