【问题标题】:Sql Group by for rows with all columns the same except oneSql Group by 用于除一之外所有列相同的行
【发布时间】:2011-12-23 18:47:01
【问题描述】:

我有一个包含许多列的表,这些列将用于保存用户存储的搜索。

每天都需要发送一封包含最新搜索结果的电子邮件。 可能有数千个已保存的搜索。

我保存的搜索表中的列类似于以下内容:

Id 
userEmail 
SearchParam1 
SearchParam2 
SearchParam3

由于会有如此多的搜索,我预计会有很多相同的搜索,因此我希望获取 param1、2 和 3 相同但仍可以访问用户电子邮件的每一行,以便我可以发送无需多次运行相同的搜索即可获得相同的结果。

理想情况下,我想要这样的东西:

SearchParam1, SearchParam2, SearchParam3
|
|____Email1
|
|____Email2
|
|____Email3

按搜索参数分组,但以某种方式链接到电子邮件。

我什至不知道从哪里开始,因此我没有添加任何代码。 谁能给我一些建议?

编辑 只是为了澄清。一封电子邮件在表格中不会出现多次。所以从技术上讲,他们每个人只能保存 1 次搜索。

没有这样的用户,只有电子邮件地址。

贝克斯

【问题讨论】:

  • 为什么不在 group by 中包含 userEmail。
  • 电子邮件会有所不同,所以如果 3 行相同但使用不同的电子邮件,不只是选择 3 个单独的行吗?除非我错过了什么?
  • @Bex:所以没有用户会运行多个查询? (或者userEmail 表示的不是用户的电子邮件地址?)
  • 没有人会运行很多查询.. 但他们会选择只保存一个结果将通过电子邮件发送!也许我的问题不清楚?
  • @Bex:我认为现在更清楚了 - 该表用于保存每个用户的首选/最近查询。在这种情况下,查询中不需要分组 - 只需排序。您表示需要的格式(仅包括更改时的 SearchParam 值)通常最好在 SQL 之外处理 - 例如,在 SSRS 中。

标签: c# sql group-by subsonic grouping


【解决方案1】:

您真正应该考虑的是数据规范化。这看起来像一个多对多的关系,所以像这样的结构将是一个想法:

create table yourUsersTable
(
    id int identity(1, 1) primary key clustered not null,
    name varchar(1000) not null,
    email varchar(1000) not null
)
go

create table searchParams
(
    id int identity(1, 1) primary key clustered not null,
    searchText varchar(1000) not null
)
go

create table userSearchParams
(
    fkYourUsersTable int not null references yourUsersTable(id),
    fkSearchParams int not null references searchParams(id)
)
go

这样,如果您想获取订阅搜索参数的用户的所有电子邮件地址,这将是一个简单的查询:

select u.email
from yourUsersTable u
inner join userSearchParams up
on u.id = up.fkYourUsersTable
inner join searchParams p
on p.id = up.fkSearchParams
where p.searchText = 'your search parameter here'

这是使用 多对多 关系实现数据规范化的基本示例。它利用连接表来创建用户和搜索参数之间的关系。通过上述设计,数据检索变得更加简单,并且您不会受到原始非规范化数据(searchParam1searchParam2 等列)的限制。

请让我知道这是否有意义。

【讨论】:

  • 这确实有道理,但我不确定它是否会起作用,或者我没有正确理解。我有 10 个命名搜索参数,即 location lat、location long、categoryId 等……所以 where 子句不存在。我需要将它们分组吗?我一定是错过了什么?
【解决方案2】:

在 SQL 中,起点是:

select SearchParam1, SearchParam2, SearchParam3, userEmail, count(*) query_count
from MyTable
group by SearchParam1, SearchParam2, SearchParam3, userEmail
order by 1,2,3,4

(如果您不想查看同一用户运行相同查询的次数,您可以省略group by 子句和count(*) 项,而只包含select distinct。)

这将在每个用户的电子邮件旁边重复搜索参数。

如果您只想在每次更改时将搜索参数作为标题包含在内,我建议在报告工具(例如 SQLServer 报告服务)中使用上述查询 - 对搜索参数进行分组,包括参数字段仅在组标题中,并且仅在详细信息行中包含用户电子邮件。

编辑:如果 userEmail 唯一标识一条记录,则查询可以简化为:

select SearchParam1, SearchParam2, SearchParam3, userEmail
from MyTable
order by 1,2,3,4

【讨论】:

  • 我稍微编辑了我的问题。一封电子邮件在表格中不会出现多次。如果我分组,它不会只为每封电子邮件提供一个单独的行吗?参数可能相同,但电子邮件永远不会。
猜你喜欢
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
相关资源
最近更新 更多