【问题标题】:SQL: Fetch rows with least date + Use CASE WHEN with select statementSQL:获取日期最少的行 + 使用 CASE WHEN 和 select 语句
【发布时间】:2017-02-04 06:32:22
【问题描述】:

我有一个包含 3 列(idtypedate)的表格,其值如下:

id    type    date
---   ---      ---
191     0    2016-09-15 11:26:51.000
191     1    2016-09-15 11:30:31.000
200     0    2016-09-15 17:36:19.000
200     1    2016-09-15 18:26:51.000
331     0    2016-09-16 07:26:22.000

这就是我想做的:

对于上面的每个ticketid,选择最短日期的行。完成后,我希望输出中的另一列名为“isEngaged”,如果ticketid 的任何记录都存在type = 1,则该列将设置为1。

我想要的输出:

id    type    date                        isEngaged
---   ---      ---                         ---
191     0    2016-09-15 11:26:51.000        1
200     0    2016-09-15 17:36:19.000        1
331     0    2016-09-16 07:26:22.000        0

这是我目前所拥有的:(这会只返回日期最少的行)

SELECT id, type, date FROM (SELECT ROW_NUMBER() OVER (PARTITION BY id ORDER BY date ASC) AS [Row], id, type, date)
      FROM mytable WHERE type IN (0)) WHERE [Row] = 1

真的不知道如何合并 isEngaged 部分。我尝试使用 CASE WHEN 但不确定如何继续:

SELECT id, type, date,
"isEngaged" = CASE WHEN (SELECT * FROM mytable where type in (1) and id = <not sure what to put here>) THEN 1 ELSE 0 END
FROM mytable

如果您知道更好的方法,请告诉我。

【问题讨论】:

    标签: sql sql-server tsql greatest-n-per-group


    【解决方案1】:
    select
    id,
    case when sum_engaged > 0 then 1 else 0 end as isEngaged,
    min_date
    from
    (SELECT id, 
    sum(case when type IN( 1,3) then 1 else 0 end) as sum_engaged, min(date) as min_date 
    FROM mytable 
    group by id) g
    

    【讨论】:

    • Hey Beth - 除了使用 sum(type) 之外,您还可以使用更通用的东西。所以目前我的类型只有 0 和 1.. 但明天我可能有 0,2,4 代表“0”,1,3 代表“1”
    • @Matt,可以单选完成,我不知道他还需要添加什么。从他的例子中,我认为他不会有超过一个目标值。
    【解决方案2】:

    如果您只接受type 列中的0/1 值,那么您可以使用MAX() 作为窗口函数。

    SELECT  
      id, type, date, isEngaged
    FROM (
      SELECT
        id, type, date,
        MAX(type) OVER (PARTITION BY id) AS isEngaged
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY date) AS rn
      FROM mytable
      ) t
    WHERE rn = 1
    

    如果您接受大于 1 的值,那么 MAX() 中的适当 CASE 语句就足够了:

    SELECT  
      id, type, date, isEngaged
    FROM (
      SELECT
        id, type, date,
        MAX(CASE WHEN type = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY id) AS isEngaged
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY date) AS rn
      FROM mytable
      ) t
    WHERE rn = 1
    

    【讨论】:

    • 谢谢卡米尔!它按预期工作。除了执行“WHERE rn = 1”之外,我如何要求查询选择具有最低 rn 的行而不指定“1”?类似“WHERE rn = min(rn)”的东西?
    • @90abyss 最低 rn 是 1。不要试图使事情复杂化 :)。这就是row_number 的工作方式。
    • @90abyss 你可能做错了,但这似乎是一个单独的问题。尝试添加另一个窗口函数并在 WHERE 中应用条件。如果您仍然遇到麻烦,请将您的努力发布为不同的 Q。
    • 所以我在上述查询的末尾还有另一个 where 条件。如果我有那个过滤器,返回的结果通常以 rn > 1 开头。因此我正在寻找另一种方法,而不是 rn = 1,我们可以在 rn 最小的地方做。
    • 你是对的!我会把它作为一个不同的问题发布。感谢您的帮助
    猜你喜欢
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多