SQL Server:如何使用group by的聚合函数来维护数据完整性?

时间:2012-04-10 12:28:47

标签: sql sql-server sql-server-2005

以下是我的问题:如何使用聚合函数和分组来保持记录完整性?

进一步解释,这是一个例子。

我有一个包含以下列的表:(将其视为“订单”表)

Customer_Summary (first 10 char of name + first 10 char of address)
Customer_Name
Customer_Address
Customer_Postal Code
Order_weekday

每个“订单”有一行,因此许多行具有相同的客户名称,地址和摘要。

我想要做的是显示客户的姓名,地址和邮政编码,以及他们在每个工作日放置的订单数量,按客户摘要分组。

所以数据看起来应该是这样的:

Summary             | Name        | Address    | PCode | Monday | Tuesday | Wednesday | Thursday | Friday

test custntest addre|test custname|test address|123456 | 1      | 1       | 1         | 1        | 1

我只想将类似客户摘要的记录组合在一起,但显然我想要显示一个名称,地址和邮政编码。我现在正在使用min(),所以我的查询看起来像:

SELECT Customer_Summary, min(customer_name), min(customer_address), min(customer_postal_code) 
FROM Order
Group by customer_summary

我省略了我的工作日逻辑,因为我觉得没必要。

我的问题是这一点 - 其中一些拥有相同客户摘要的客户有不同的地址和邮政编码。

所以我可能有两个客户,看起来像:

test custntest addre|test custname |test address |323456|

test custntest addre|test custname2|test address2|123456|

使用group by,我的查询将返回以下内容:

test custntest addre|test custname |test address |123456|

由于我使用min,它会给我所有字段的最小值,但不一定来自同一记录。所以我在这里丢失了我的记录完整性 - 查询返回的地址和名称与邮政编码没有正确匹配。

那么在使用group by子句时如何在非分组字段上维护数据完整性?

希望我能够清楚地解释清楚,并提前感谢您的帮助。

编辑:解决了。谢谢大家!

2 个答案:

答案 0 :(得分:3)

您始终可以使用ROW_NUMBER代替GROUP BY

WITH A AS (
    SELECT Customer_Summary, customer_name, customer_address, customer_postal_code,
        ROW_NUMBER() OVER (PARTITION BY Customer_Summary ORDER BY customer_name, customer_address) AS rn
    FROM Order
)
SELECT Customer_Summary, customer_name, customer_address, customer_postal_code
FROM A
WHERE rn = 1

然后您可以自由订购在ORDER BY子句中使用的客户。目前,我按名称订购,然后致电。

修改

我的解决方案符合您的要求。但我肯定同意其他人:如果你被允许改变数据库结构,这将是一个好主意......你不是(看到你的评论)。好吧,那么ROW_NUMBER()是一个好方法。

答案 1 :(得分:3)

我认为你需要重新思考你的结构。

理想情况下,您将拥有一个具有唯一ID的Customer表。然后,您将在Order表中使用该唯一ID。然后你不需要你正在使用的奇怪的“前10个字符”方法。相反,您只需按Customer表中的唯一ID进行分组。

您甚至可以拥有一个单独的地址表,将每个地址与客户相关联,多行(其中字段标记为家庭住址,送货地址,帐单地址等)

这样您就可以将客户信息与地址信息和订单信息分开。这样,如果客户更改姓名(婚姻)或地址(搬家),则不会破坏您的数据 - 所有内容都与ID相关,而不是数据本身。

[此关系称为外键。]