【问题标题】:Applying Where clause for Order by in SQL在 SQL 中为 Order by 应用 Where 子句
【发布时间】:2012-12-24 14:09:00
【问题描述】:

希望按照基于like子句的关键字选择顺序允许的方式对以下数据进行排序:

表格中的数据:

EmpId EmpLotusNotes
10001 Amit B/India
20002 Bharat C/India
30003 Kyo Jun/Japan
40004 Jee Lee/China
50005 Xavier K/USA

要根据特定国家顺序(日本、中国、印度、美国)呈现/排序的数据:

EmpId EmpLotusNotes
30003 Kyo Jun/Japan
40004 Jee Lee/China
10001 Amit B/India
20002 Bharat C/India
50005 Xavier K/USA

注意:我无法创建另一个包含国家/地区顺序或任何其他更改的表。

【问题讨论】:

  • 请发布您的 SQL SELECT 子句,如果没有,我们将无能为力。如果你能创建一个SQLFiddle,那就太棒了……
  • 国家名称是在单独的列中还是在 EmpLotusNotes 列中的一部分?
  • 这看起来与之前的答案非常相似:stackoverflow.com/questions/13196010/…
  • @twoleggedhorse 谢谢。看起来会有所帮助。
  • 为什么日本排在中国之前?政治原因;)?

标签: sql sql-server-2008 sorting sql-order-by where-clause


【解决方案1】:

这应该是一个技巧:

SELECT
   EmpId, EmpLotusNotes
FROM 
   dbo.Table
ORDER BY
   CASE 
      WHEN EmpLotusNotes LIKE '%Japan' THEN 1
      WHEN EmpLotusNotes LIKE '%China' THEN 2 
      WHEN EmpLotusNotes LIKE '%India' THEN 3
      WHEN EmpLotusNotes LIKE '%USA' THEN 4
   END

【讨论】:

    【解决方案2】:

    问题是表格违反了第一范式,EmpLotusNotes 不应包含员工姓名和国家/地区,大概是他们工作的国家/地区。

    你应该质疑不允许你清理结构和数据的原因。

    https://www.google.com.au/search?q=sql+first+normal+form+atomic

    如果你在挑战后仍然无法规范化数据库,答案是为国家创建一个查询,创建一个查询将第一个表中的数据拆分为第一个范式,然后将两者连接起来。

    下面是一个适用于 mysql 的示例,对于 MS SQL,您将使用 CHARINDEX 而不是 INSTR 和 substring 而不是 substr。

    select employeesWithCountries.*
    , countries.sort 
    from (
        select empId, empLotusNotes, substr( empLotusNotes, afterStartOfDelimiter ) country from (
            select empId
            , empLotusNotes
            , INSTR( empLotusNotes, '/' ) + 1 as afterStartOfDelimiter 
            from EmployeesLotusNotes
        ) employees
    ) employeesWithCountries
    inner join (
        SELECT 'Japan' as country, 1 as sort
        union
        SELECT 'China' as country, 2 as sort
        union
        SELECT 'India' as country, 3 as sort
        union
        SELECT 'USA' as country, 4 as sort
    ) countries
    on employeesWithCountries.country = countries.country
    order by countries.sort, employeesWithCountries.empLotusNotes
    

    结果。

    30003    Kyo Jun/Japan   Japan    1
    40004    Jee Lee/China   China    2
    10001    Amit B/India    India    3
    20002    Bharat C/India  India    3
    50005    Xavier K/USA    USA      4
    

    【讨论】:

      【解决方案3】:

      也许:

      SELECT
         EmpId, EmpLotusNotes
      FROM 
         dbo.Table
      ORDER BY
         CASE WHEN EmpLotusNotes LIKE '%Japan' THEN 0 ELSE 1 END,
         CASE WHEN EmpLotusNotes LIKE '%China' THEN 0 ELSE 1 END,
         CASE WHEN EmpLotusNotes LIKE '%India' THEN 0 ELSE 1 END,
         CASE WHEN EmpLotusNotes LIKE '%USA' THEN 0 ELSE 1 END
      

      这是DEMO

      【讨论】:

        【解决方案4】:

        您可以先使用公用表表达式处理原始数据,然后再对处理后的数据进行过滤和/或排序。像下面的东西。 myCol 中的函数可以用任何类型的函数进行更改,甚至是 CASE 子句。

        WITH T as 
        (SELECT EmpId, EmpLotusNotes, SOMEFUNCTION(EmpLotusNotes) as myCol
         FROM Table1
        )
        SELECT *
        FROM T 
        WHERE myCol = XXX
        ORDER BY myCol
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-24
          • 2016-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多