如何实现自定义SQL聚合或比较器功能?

时间:2015-09-11 22:06:30

标签: sql sql-server aggregate-functions comparator

鉴于下表,我需要生成一个结果,显示所选范围的可用性。可用性规则规定了X,?,'',Y的顺序。例如,给定以下数据集:

+------------+--------------+------+
| date       | availability | id   |
+------------+--------------+------+
| 2015-09-01 | X            |    1 |
| 2015-09-02 | X            |    1 |
| 2015-09-03 | X            |    1 |
| 2015-09-04 | X            |    1 |
| 2015-09-01 | X            |    2 |
| 2015-09-02 | ?            |    2 |
| 2015-09-03 | X            |    2 |
| 2015-09-04 | X            |    2 |
| 2015-09-01 | ''           |    3 |
| 2015-09-02 | Y            |    3 |
| 2015-09-03 | Y            |    3 |
| 2015-09-04 | Y            |    4 |
| 2015-09-01 | Y            |    4 |
| 2015-09-02 | Y            |    4 |
| 2015-09-03 | Y            |    4 |
| 2015-09-04 | Y            |    4 |
+------------+--------------+------+

我想要的输出是:

+--------------+------+
| availability | id   |
+--------------+------+
| X            |    1 |
| ?            |    2 |
| ''           |    3 |
| Y            |    4 |
+--------------+------+

我知道如果我正在处理数值,我可以使用MIN MAX等等。我的问题是,SQL是否为我提供了一种简单的方法来定义自定义聚合或比较器函数来实现这个逻辑?

我使用Azure SQL,如果不同的供应商有不同的解决方案。

2 个答案:

答案 0 :(得分:2)

只需使用优先级排序逻辑:

select ids.id, a.availability
from (select distinct id from table t) ids cross apply
     (select top 1 availability
      from table t2
      where t2.id = t.id
      order by (case when availability = 'X' then 1
                     when availability = '?' then 2
                     when availability = '' then 3
                     when availability = 'Y' then 4
                     else 5
                end)
     ) a;

如果你有一个单独的id表,那么你应该使用它而不是子查询。

还有其他方法;但是,我能够轻易想到的那些需要更复杂的case语句,两个连接或更复杂的SQL。您不需要“自定义聚合”。您只需要弄清楚如何确定结果的优先级。

答案 1 :(得分:0)

由于您尚未接受戈登的回答,因此我将直接回答这个问题:

  

我的问题是,SQL是否给我一种定义自定义的简单方法   聚合或比较器功能来实现此逻辑?

不,不是。