【问题标题】:SQL SELECT DISTINCT and GROUP BY problemSQL SELECT DISTINCT 和 GROUP BY 问题
【发布时间】:2010-12-05 18:07:20
【问题描述】:

我只需要为每个特定的数据库条目返回 1 行。例如如果我有:

ID col1 col2
1    1    A
2    1    B
3    1    C
4    2    D
5    3    E
6    4    F
7    4    G

在 MySQL 中我可以运行查询

SELECT DISTINCT col1, col2 FROM table GROUP BY col1

我会得到 ->

ID col1 col2
1    1    A
4    2    D
5    3    E
6    4    F

这是我想要的,但如果我在 SQL Server 中运行相同的查询,我会收到错误..

所以,基本上我只需要从表中的每一行返回一个(或第一个)“col1”及其“col2”。

SQL Server 的正确语法是什么?

感谢您的宝贵时间!

安德烈

编辑:

在 mysql 中工作的完整查询是 ->

SELECT DISTINCT list_order, category_name, category_id
FROM  `jos_vm_category` 
WHERE  `category_publish` =  'Y'
GROUP BY list_order

所以,对于每个“list_order”编号,我想从该行返回 category_name 和 category_id,并忽略具有相同“list_order”编号的所有其他行

【问题讨论】:

  • @marc_s:我猜 OP 得到的错误是 SQL Server 要求所有 SELECT 字段出现在 GROUP BY 子句中,除非它们是聚合函数的一部分。 MySQL 不需要这个。
  • 在 MSSQL 中,错误是“列 'jos_vm_category.category_id' 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。”

标签: sql mysql sql-server


【解决方案1】:

另一种方法是在 T-SQL 中使用 ROW_NUMBER() 函数,它允许您通过某些东西“分区”您的数据 - 就像这里的 col1 一样 - 并为每个数据分区获取增量数字。如果您只想要每个“分区”的第一个条目,只需以这种方式查询它(使用公用表表达式 - CTE):

;WITH Distincts AS
(
    SELECT ID, col1, col2,
        ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY ID) AS 'RowNo'
    FROM dbo.Table
)
SELECT
    ID, col1, col2
FROM
    Distincts
WHERE
    RowNo = 1

这给了我你正在寻找的输出。

【讨论】:

  • 看起来我来晚了 :).. 但有一个更简单的选择
  • @Roopesh - 您的替代方案效率较低,我也不同意它更简单。
  • @Martin - 我不同意 - 在我的答案中发布查询计划比较。
  • @roopesh -“相对于批次的查询成本”不是一个可靠的指标,因为它基于基数估计,即使在实际执行计划中也是如此。你有没有麻烦填充表格?如果是这样,您的脚本是什么? SET STATISTICS IO ONSET STATISTICS TIME ON 说什么?还要添加合理的索引以摆脱计划中的sort
  • @Martin - 不.. 猜你一直都是对的,至少对于我生成的数据而言。让我相信估计的成本是正确的。 :)
【解决方案2】:

你可以获取col1中第一个值实例对应的所有行,如下所示

SELECT col1, col2
FROM table t1
where not exists 
      (select 1 
         from table t2
        where t2.col1 = t1.col1 and
              t2.id < t1.id)

编辑:发布查询比较

EDIT2:贴出实际查询执行计划的对比,随机生成了大约2000行数据,id为唯一索引的标识列。 id 和 col1 上的第二个索引。

事实证明,Marc 的查询毕竟更快,至少有这些数据!

【讨论】:

    猜你喜欢
    • 2020-11-05
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2023-04-11
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    相关资源
    最近更新 更多