【问题标题】:How to return only 1 (specific) instance of column value when multiple instances exist存在多个实例时如何仅返回列值的 1 个(特定)实例
【发布时间】:2014-01-24 03:45:45
【问题描述】:

我有以下名为“timtest”的示例表:

itemcode     qty_available  date
apple        0              1/23/2014
apple        96             1/27/2014
apple        136            2/15/2014
orange       12             1/23/2014
orange       48             2/5/2014
peach        0              1/23/2014
peach        300            2/5/2014
peach        315            2/10/2014
peach        330            2/15/2014
banana       0              1/23/2014
pineapple    24             1/23/2014

我只想要 itemcode 列中每个唯一值的一个实例。选择为每个唯一项目代码选择哪一行的标准基于数量大于零和任何数量大于零的最快日期可用。如果今天有大于零的可用数量,我想返回该行。如果今天日期可用的数量为 0,我想在最近的将来找到下一个可用记录,其中任何数量大于零并返回该行。如果今天的数量为零并且没有其他未来日期,我想返回显示为零的行。此表永远不会有过去的日期,所有记录都会有一个带有今天日期的条目。

这是从上述样本数据中得到的期望结果集,考虑到今天是1/23/2014

itemcode    qty_available   date
apple       96              1/27/2014
orange      12              1/23/2014
peach       300             2/5/2014
banana      0               1/23/2014
pineapple   24              1/23/2014

你能帮我正确查询吗?

【问题讨论】:

    标签: mysql sql distinct partitioning


    【解决方案1】:

    我认为这是您想要获取日期的逻辑:

    select itemcode,
           coalesce(min(case when qty_available > 0 then date end), min(date)) as thedate
    from timtest tt
    where date >= date(now())
    group by itemcode;
    

    表达式coalesce(min(case when qty > 0 then date end), min(date)) 似乎封装了您的逻辑。合并的第一部分返回qty > 0 时的第一个日期。如果这些都不存在,那么它会找到0 的第一个日期。你不说今天没有记录怎么办,但是0将来有记录。这将返回第一个这样的记录。

    要获得数量,让我们回到这个:

    select tt.*
    from timtest tt join
         (select itemcode,
                 coalesce(min(case when qty_available > 0 then date end), min(date)) as thedate
          from timtest tt
          where date >= date(now())
          group by itemcode
         ) id
         on tt.itemcode = id.itemcode and tt.date = id.thedate;
    

    编辑:

    不考虑错误的日期格式。这是针对这种情况的一个版本:

    select tt.*
    from timtest tt join
         (select itemcode,
                 coalesce(min(case when qty_available > 0 then thedate end), min(thedate)) as thedate
          from (select tt.*, str_to_date(date, '%m/%d/%Y') as thedate
                from timtest tt
               ) tt
          where thedate >= date(now())
          group by itemcode
         ) id
         on tt.itemcode = id.itemcode and str_to_date(tt.date, '%m/%d/%Y') = id.thedate;
    

    对未来的建议:将数据库中的日期存储为日期/日期时间数据时间,而不是字符串。如果您将它们存储为字符串,请使用 YYYY-MM-DD 格式,因为您可以使用比较和order by

    【讨论】:

    • 现在使用上面的文字示例,查询返回一个空结果集。日期在 mysql 数据库中为 VARCHAR(10) mm/dd/yyy ...这是导致查询不起作用的原因吗?我需要在这里添加一些东西来转换查询结果中的日期吗?如果是这样,你知道我该怎么做吗?
    • 我尝试了以下方法,它似乎为表中的每一行提供了 5 行相同的行,并且不忽略任何行/记录。 select tt.* from timtest tt join (select itemcode, coalesce(min(case when qty_available > 0 then (DATE_FORMAT(date,'%m/%d/%Y')) end), min(DATE_FORMAT(date,'% m/%d/%Y'))) as thedate from timtest tt where date >= DATE_FORMAT(now() , '%m/%d/%Y') group by itemcode ) 任何想法出了什么问题?
    • 没关系。您的查询完全符合书面要求。我之前没有全部复制。
    • @TimS 。 . . DATE_FORMAT() 接受一个日期并以参数中指定的格式生成它。 希望字符串成为日期。所以,在提供的代码中使用str_to_date()
    猜你喜欢
    • 2018-09-05
    • 1970-01-01
    • 2023-03-05
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    相关资源
    最近更新 更多