如何在 SQL 中进行列式和行式操作
How to do column-wise and row-wise operations in SQL
我对 SQL 查询中的行式和列式操作有疑问。我将使用以下示例数据 table:
来证明我的问题
Person Income Hours worked Day
A 100 10 1
A 200 9 2
B 300 8 1
B 400 7 2
C 500 6 1
C 600 5 2
我想编写一个查询,从中获取 (A + B) 和 C 的总收入、工作时间和每小时收入。即:
Person Income Hours worked Income / Hour
A + B 1000 34 1000 / 34
C 1100 11 1100 / 11
我如何在 SQL 中执行此操作?
非常感谢!
您可以使用 case
表达式将包含 A
、B
的行视为相同的行并汇总。
select
case when person in ('A','B') then 'A+B' else person end as person
,sum(income) as income
,sum(hoursworked) as hoursworked
,sum(income)/sum(hoursworked) as income_hour
from yourtable
group by case when person in ('A','B') then 'A+B' else person end
您可以在子查询中使用 UNION ALL
SELECT Person, Income, [Hours worked], [Income / Hour]
FROM (
SELECT 'A + B' AS Person,
SUM(Income) AS Income,
SUM([Hours worked]) AS [Hours worked],
SUM([Day]) AS [Hours worked]
FROM dbo.TableName
WHERE Person IN('A', 'B')
UNION ALL
SELECT 'C' AS Person,
SUM(Income) AS Income,
SUM([Hours worked]) AS [Hours worked],
SUM([Day]) AS [Hours worked]
FROM dbo.TableName
WHERE Person = 'C'
) x
如果要排序,可以在外部查询上应用 ORDER BY
。
对于MySQL,我们可以这样做:
SELECT CASE WHEN t.Person IN ('A','B') THEN 'A + B' ELSE t.Person END AS Person
, SUM(t.Income) AS Income
, SUM(t.`Hours Worked`) AS `Hours Worked`
, CONCAT( SUM(t.Income) , ' / ' , SUM(t.`Hours Worked`) ) AS `Income / Hour`
FROM mytable t
GROUP BY CASE WHEN t.Person IN ('A','B') THEN 'A + B' ELSE t.Person END
同样的模式适用于大多数其他关系数据库,但对转义不稳定的列名的处理不同。
对于 Oracle,用双引号而不是反引号将标识符括起来。 (即用双引号替换反引号,并括起包含小写字母或其他特殊字符的列名。)
对于 SQL 服务器,将标识符括在方括号中... [Hours Worked]
.
只是为了提供另一种方法,这里有一个 UNION 方法:
SELECT 'A + B', sum(income) as income, sum(hoursworked) as hoursworked sum(income)/sum(hoursworked) as income_hour
FROM yourtable
WHERE person in ('A','B')
UNION ALL
SELECT person, sum(income) as income, sum(hoursworked) as hoursworked sum(income)/sum(hoursworked) as income_hour
FROM yourtable
WHERE person NOT in ('A','B')
GROUP BY person
编辑:蒂姆更快。
我对 SQL 查询中的行式和列式操作有疑问。我将使用以下示例数据 table:
来证明我的问题Person Income Hours worked Day
A 100 10 1
A 200 9 2
B 300 8 1
B 400 7 2
C 500 6 1
C 600 5 2
我想编写一个查询,从中获取 (A + B) 和 C 的总收入、工作时间和每小时收入。即:
Person Income Hours worked Income / Hour
A + B 1000 34 1000 / 34
C 1100 11 1100 / 11
我如何在 SQL 中执行此操作?
非常感谢!
您可以使用 case
表达式将包含 A
、B
的行视为相同的行并汇总。
select
case when person in ('A','B') then 'A+B' else person end as person
,sum(income) as income
,sum(hoursworked) as hoursworked
,sum(income)/sum(hoursworked) as income_hour
from yourtable
group by case when person in ('A','B') then 'A+B' else person end
您可以在子查询中使用 UNION ALL
SELECT Person, Income, [Hours worked], [Income / Hour]
FROM (
SELECT 'A + B' AS Person,
SUM(Income) AS Income,
SUM([Hours worked]) AS [Hours worked],
SUM([Day]) AS [Hours worked]
FROM dbo.TableName
WHERE Person IN('A', 'B')
UNION ALL
SELECT 'C' AS Person,
SUM(Income) AS Income,
SUM([Hours worked]) AS [Hours worked],
SUM([Day]) AS [Hours worked]
FROM dbo.TableName
WHERE Person = 'C'
) x
如果要排序,可以在外部查询上应用 ORDER BY
。
对于MySQL,我们可以这样做:
SELECT CASE WHEN t.Person IN ('A','B') THEN 'A + B' ELSE t.Person END AS Person
, SUM(t.Income) AS Income
, SUM(t.`Hours Worked`) AS `Hours Worked`
, CONCAT( SUM(t.Income) , ' / ' , SUM(t.`Hours Worked`) ) AS `Income / Hour`
FROM mytable t
GROUP BY CASE WHEN t.Person IN ('A','B') THEN 'A + B' ELSE t.Person END
同样的模式适用于大多数其他关系数据库,但对转义不稳定的列名的处理不同。
对于 Oracle,用双引号而不是反引号将标识符括起来。 (即用双引号替换反引号,并括起包含小写字母或其他特殊字符的列名。)
对于 SQL 服务器,将标识符括在方括号中... [Hours Worked]
.
只是为了提供另一种方法,这里有一个 UNION 方法:
SELECT 'A + B', sum(income) as income, sum(hoursworked) as hoursworked sum(income)/sum(hoursworked) as income_hour
FROM yourtable
WHERE person in ('A','B')
UNION ALL
SELECT person, sum(income) as income, sum(hoursworked) as hoursworked sum(income)/sum(hoursworked) as income_hour
FROM yourtable
WHERE person NOT in ('A','B')
GROUP BY person
编辑:蒂姆更快。