【问题标题】:Interesting SQL Sorting Issue有趣的 SQL 排序问题
【发布时间】:2010-05-06 04:31:40
【问题描述】:

现在是关键时刻,我最近一份合同的截止日期将在两天后到来,除了一个问题外,几乎所有东西都已完成并且工作正常(敲木头)。

在我的一个存储过程中,我需要返回一个结果集,如下所示。

group_id      name
--------      --------
A101          Craig
A102          Craig
Z101          Craig
Z102          Craig
A101          Jim
A102          Jim
Z101          Jim
Z102          Jim
B101          Andy
B102          Andy
Z101          Andy
Z102          Andy

名称需要按组 id 的第一个字符排序,并且还包括 Z101/Z102 条目。通过严格按组 id 排序,我得到如下结果集:

group_id      name
--------      --------
A101          Craig
A102          Craig
A101          Jim
A102          Jim
B101          Andy
B102          Andy
Z101          Andy
Z102          Andy
Z101          Craig
Z102          Craig
Z101          Jim
Z102          Jim

我真的想不出一个不涉及我制作游标和使存储过程膨胀得比现在更多的解决方案。我敢肯定,一个伟大的头脑有一个优雅的解决方案,我很想看看社区能想出什么。

非常感谢。

编辑:让我扩展一下 :) 对不起,太晚了,我喝咖啡上瘾了。

上述结果集是一种特殊类型数据输入的特例。为透明起见,我们正在制作一个基于选举的网站,这些候选人将按职位、姓名和地区排序。

除了治安官/验尸官等地区职位只有一个之外,大多数办公室都有多个区。 Z 是缺席机器和缺席纸票的“区”。

非治安官职位可以先按名称排序,因为它们都是组合在一起的。然而,现有系统在大量信息中列出了所有治安官,而他们应该按各个地区进行分类。这就是问题所在。

为了保护我的自尊心,我想补充一点,我无法控制数据库的规范化。这是客户给我的。

这是我的存储过程的 order 子句,如果有帮助的话:

    ORDER BY    candidate.party,
            candidate.ballot_name,  
CASE WHEN       candidate.district_type = 'MAG' THEN LEFT(votecount.precinct_id, 1) END,
        candidate.last_name,
        candidate.first_name,
        precinct.name

编辑 2:这是我目前所处的位置(凌晨 1 点 43 分)-

我正在使用以下建议来创建条件内部联接,如下所示:

    IF          candidate.district_type = 'MAG'
BEGIN
    (
        SELECT candidate.id AS candidate_id, candidate.last_name, LEFT(votecount.precinct_id, 1) AS district, votecount.precinct_id
        FROM candidate
        INNER JOIN votecount
        ON votecount.candidate_id = candidate.id
        GROUP BY name
    ) mag_order
    INNER JOIN      mag_order
    ON              mag_order.candidate_id = candidate.id
END

然后我将按照 mag_order.district、candidate.precinct_id、candidate.last_name 对其进行排序。

由于某种原因,在将 (SELECT) 别名为 mag_order 时出现 SQL 错误。有人看到代码有什么问题吗?我不能为我的生活。抱歉,这有点切题。

【问题讨论】:

  • 嗨,我不明白这个要求。如果要按group_id的第一个字符排序,是不是输出不正确? Z101Craig 的组合是从哪里来的,或者......它在第二张桌子上的位置是哪里?您能否发布一些示例完整输入、您想要的输出以及您实际获得的输出,因为我怀疑您只是发布部分数据并将其截断。
  • 我将尝试修改您的标准,请发表评论(或更新您的问题):您想按 group_id 的第一个字符排序,这意味着 A 在 B 之前出现在 C 之前,等等。然后对于 A,您想按名称排序,这意味着 Andy 将出现在 Craig 之前(除了 Andy 没有任何 A)。然而,一旦你决定要搭上 Craig,你也会想要他所有的 Z。
  • 我认为 ORDER BY name, group_id 是您所需要的,但这取决于是否比顶部的 Craig/etc 分组更重要。
  • @OMG Ponies 实际上,如果你仔细看,它比这更复杂
  • @Lasse V. Karlsen 是的,基本上我需要它严格按 group_id 的第一个字符排序,并在结果末尾包含 Z 作为任意 group_id。很复杂=-/

标签: sql stored-procedures logic


【解决方案1】:
SELECT g1.group_id, g1.name
FROM 
    groups g1
        INNER JOIN
    (
        SELECT  MIN(group_id), name
        FROM groups
        GROUP BY name
    ) g2 on g1.name = g2.name
ORDER BY g2.group_id, g1.name, g1.group_id

【讨论】:

  • 这个解决方案非常接近。唯一的问题是我上面所说的是大量返回数据中的一个特例。大约 20% 的返回数据需要按照我要求的方式处理,另外 80% 是简单的 [order by name, group_id]。我将尝试一下您的解决方案并尝试使其适合。非常感谢。
  • @rofly,您拥有的排序集包含 Craig、Jim、Andy。我不确定这与“name,group_id”的 80% 有什么关系。可能需要更大的数据集样本和预期结果(以及测试数据 ddl/inserts)。
【解决方案2】:

ORDER BY name DESC, SUBSTR(group_id,1), group_id

【讨论】:

    【解决方案3】:
    SELECT groupId, name
    FROM table
    ORDER BY getFirstGroupId(name), name, groupId
    

    然后您的 getFirstGroupId() 函数将返回该名称的第一个 groupId

    SELECT MIN(groupId)
    FROM groupTable
    WHERE name = @name
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2014-02-03
      • 2012-03-10
      相关资源
      最近更新 更多