我是SQL Server的新手/用于MySQL数据库,我遇到了一个我从未遇到过MySQL的问题。我希望提取所有当前的保单号码,公司/所属人员的姓名,总保费,以及他们是否拥有我们所称的设备故障'覆盖。这一切都很简单,我遇到的问题是分组。我想只分组一列,也就是一个不同的政策编号,公司名称,保险费总和(可能有几个保费金额,无论是负面的还是正面的,所以我想总结这些,看看真正的总数是多少),以及设备故障的简单“是”或“否”列。
这是我正在运行的查询:
SELECT pol_num as policy_number,
insd_name as insureds_name,
SUM(amt) as 'total_premium',
(SELECT
CASE
WHEN cvg_desc = 'Equipment Breakdown'
THEN 'Y'
ELSE 'N'
END) as 'equipment_breakdown'
FROM bapu.dbo.fact_prem
WHERE '2014-05-06' between d_pol_eff and d_pol_exp
AND amt_type = 'Premium'
AND amt_desc = 'Written Premium'
GROUP BY pol_num
ORDER BY policy_number
我收到一条错误消息,说我需要按照insd_name和cvg_desc分组,但我不想这样,因为它给了我重复的政策号码。
以下是我将其告诉我的一切分组后得到的一个例子:
policy_number insureds_name total_premium equipment_breakdown
001 company a 0.00 n
001 company a 25,000.00 n
001 company a -10,000.00 n
002 company b 100.00 y
002 company b 10,000.00 y
以下是我想要的结果示例:
policy_number insureds_name total_premium equipment_breakdown
001 company a 15,000.00 n
002 company b 10,100.00 y
基本上,我只想按保单编号分组并汇总保费金额。以上是我在MySQL中实现这一目标的方法,如何在SQL Server中实现我想要的结果?
由于
答案 0 :(得分:1)
MySQL并不要求所有非聚合字段都包含在GROUP BY
子句中,即使不这样做也会产生意外结果。 SQL Server需要这样做,因此您不得不决定如何处理给定insd_name
的多个pol_num
值,您可以使用MAX()
,MIN()
,或者如果值始终相同,只需将它们添加到GROUP BY
:
SELECT pol_num AS policy_number
, MAX(insd_name) AS insureds_name
, SUM(amt) AS 'total_premium'
, MAX(CASE WHEN cvg_desc = 'Equipment Breakdown' THEN 'Y'
ELSE 'N'
END) AS 'equipment_breakdown'
FROM bapu.dbo.fact_prem
WHERE '2014-05-06' BETWEEN d_pol_eff AND d_pol_exp
AND amt_type = 'Premium'
AND amt_desc = 'Written Premium'
GROUP BY pol_num
ORDER BY policy_number
或者:
SELECT pol_num AS policy_number
, insd_name AS insureds_name
, SUM(amt) AS 'total_premium'
, CASE WHEN cvg_desc = 'Equipment Breakdown' THEN 'Y'
ELSE 'N'
END AS 'equipment_breakdown'
FROM bapu.dbo.fact_prem
WHERE '2014-05-06' BETWEEN d_pol_eff AND d_pol_exp
AND amt_type = 'Premium'
AND amt_desc = 'Written Premium'
GROUP BY pol_num
, insd_name
, CASE WHEN cvg_desc = 'Equipment Breakdown' THEN 'Y'
ELSE 'N'
END
ORDER BY policy_number
答案 1 :(得分:1)
看起来cvg_desc
列可能会让你感到烦恼。您希望按照Y
语句中生成的N
或CASE
进行分组,但SQL服务器按原始cvg_desc
列进行分组。您可以通过在分组之前解析CASE
语句的方式来解决此问题。例如,将主查询包装在公用表表达式(CTE)中,这类似于内联视图。然后,将设备细分列减少到Y
或N
,CTE的SUM
聚合premium
后续查询应该会为您提供所需的结果:
WITH Policies(policy_number, insureds_name, premium, equipment_breakdown) AS
(
SELECT
pol_num
,insd_name
,amt
,(CASE WHEN cvg_desc = 'Equipment Breakdown' THEN 'Y' ELSE 'N' END)
AS 'equipment_breakdown'
FROM
bapu.dbo.fact_prem
WHERE
'2014-05-06' BETWEEN d_pol_eff AND d_pol_exp
AND
amt_type = 'Premium'
AND
amt_desc = 'Written Premium'
)
SELECT
policy_number
,insureds_name
,SUM(premium) AS total_premium
,equipment_breakdown
FROM
Policies
GROUP BY
policy_number
,insureds_name
,equipment_breakdown
答案 2 :(得分:0)
您需要在您不想分组的字段上使用汇总功能。一个简单的使用方法是MAX
,适用于大多数类型;
SELECT pol_num as policy_number,
MAX(insd_name) as insureds_name,
SUM(amt) as 'total_premium',
(SELECT
CASE
WHEN MAX(cvg_desc) = 'Equipment Breakdown'
THEN 'Y'
ELSE 'N'
END) as 'equipment_breakdown'
FROM bapu.dbo.fact_prem
WHERE '2014-05-06' between d_pol_eff and d_pol_exp
AND amt_type = 'Premium'
AND amt_desc = 'Written Premium'
GROUP BY pol_num
ORDER BY policy_number
SQL Server想要这个的原因是它喜欢给出确定性答案,例如
column_a | column_b
1 | 1
1 | 2
...仅由column_a
分组将在MySQL中给出1或2作为column_b
的答案,而SQL Server希望您明确告诉它使用哪一个。
答案 3 :(得分:0)
我可能会写如下 - 没有测试
SELECT pol_num as policy_number,
insd_name as insureds_name,
SUM(amt) as total_premium
CASE
WHEN cvg_desc = 'Equipment Breakdown'
THEN 'Y'
ELSE 'N'
END as equipment_breakdown
FROM bapu.dbo.fact_prem
WHERE '2014-05-06' between d_pol_eff and d_pol_exp
AND amt_type = 'Premium'
AND amt_desc = 'Written Premium'
GROUP BY
pol_num, policy_number,
CASE
WHEN cvg_desc = 'Equipment Breakdown'
THEN 'Y'
ELSE 'N'
END
ORDER BY policy_number