Mysql 查询以查找最近的日期

Mysql 查询以查找最近的日期,mysql,sql,case,aggregate-functions,Mysql,Sql,Case,Aggregate Functions,我有一张有午餐生效日期和价格的桌子 我需要显示为每个日期列创建的最接近的较短生效日期的费率 午餐价格表: 以下是我试图做的: SELECT userId, SUM(CASE WHEN date= '2018-06-01' AND lunchStatus = 1 THEN (SELECT MAX(rate) FROM lunch_rate WHERE DATE(created_on) <= date LIMIT 1) ELSE 0 END) '2018-06-01',

我有一张有午餐生效日期和价格的桌子

我需要显示为每个日期列创建的最接近的较短生效日期的费率

午餐价格表:

以下是我试图做的:

    SELECT userId, 
    SUM(CASE WHEN date= '2018-06-01' AND lunchStatus = 1 THEN (SELECT MAX(rate) FROM lunch_rate WHERE DATE(created_on) <= date LIMIT 1) ELSE 0 END) '2018-06-01',
    SUM(CASE WHEN date= '2018-06-02' AND lunchStatus = 1 THEN (SELECT MAX(rate) FROM lunch_rate WHERE DATE(created_on) <= date LIMIT 1) ELSE 0 END) '2018-06-02',
    SUM(CASE WHEN date= '2018-06-03' AND lunchStatus = 1 THEN (SELECT MAX(rate) FROM lunch_rate WHERE DATE(created_on) <= date LIMIT 1) ELSE 0 END) '2018-06-03',
    SUM(CASE WHEN date= '2018-06-04' AND lunchStatus = 1 THEN (SELECT MAX(rate) FROM lunch_rate WHERE DATE(created_on) <= date LIMIT 1) ELSE 0 END) '2018-06-04'
    FROM
    (        
        SELECT userId, lunchStatus, DATE(issuedDateTime) as date 
        FROM `lunch_status` 
        WHERE DATE(issuedDateTime) BETWEEN '2018-06-01' AND '2018-06-04'        
    ) as a
    GROUP BY userId;
预期成果:

userId    |   2018-06-01   |   2018-06-02  |  2018-06-03  |  2018-06-04
------------------------------------------------------------------------
131       |   30           |   30          |   0          |  60   
132       |   30           |   30          |  30          |   0
133       |   0            |    0          |   0          |  60
134       |   0            |    0          |   0          |  60

SUM(CASE WHEN ... THEN (SELECT MAX(rate) FROM lunch_rate WHERE DATE(created_on) <= date LIMIT 1) ELSE 0 END) ....',

如何选择当天有效的午餐价格?

您可以尝试以下方法:

SELECT lr1.rate
FROM   lunch_rate lr1
WHERE  lr1.created_on <= my_date
  AND  NOT EXISTS (SELECT *
                   FROM   lunch_rate lr2
                   WHERE  lr2.created_on > lr1.created_on
                     AND  lr2.created_on <= my_date);

您可以尝试以下方法:

SELECT lr1.rate
FROM   lunch_rate lr1
WHERE  lr1.created_on <= my_date
  AND  NOT EXISTS (SELECT *
                   FROM   lunch_rate lr2
                   WHERE  lr2.created_on > lr1.created_on
                     AND  lr2.created_on <= my_date);

如果我理解正确,您希望在子查询中进行计算:

SELECT userId, 
       SUM(CASE WHEN date = '2018-06-01' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-01`,
       SUM(CASE WHEN date = '2018-06-02' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-02`,
       SUM(CASE WHEN date = '2018-06-03' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-03`,
       SUM(CASE WHEN date = '2018-06-04' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-04`
FROM (SELECT ls.*, DATE(ls.issuedDateTime) as date
             (SELECT lr.rate
              FROM lunch_rate lr
              WHERE DATE(lr.created_on) <= DATE(ls.issuedDateTime)
              ORDER BY lr.created_on DESC
              LIMIT 1
             ) as rate
      FROM lunch_status ls
      WHERE DATE(issuedDateTime) BETWEEN '2018-06-01' AND '2018-06-04'        
     ) lr
GROUP BY lr.userId;
请注意其他变化:

午餐价格的子查询不使用MAX。而是使用ORDER BY。 列别名由反勾号包围,而不是单引号。我不赞成这些名字,因为它们需要转义。但如果需要,请使用适当的转义字符。 表具有合理的别名,列名是限定的。
如果我理解正确,您希望在子查询中进行计算:

SELECT userId, 
       SUM(CASE WHEN date = '2018-06-01' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-01`,
       SUM(CASE WHEN date = '2018-06-02' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-02`,
       SUM(CASE WHEN date = '2018-06-03' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-03`,
       SUM(CASE WHEN date = '2018-06-04' AND lunchStatus = 1
                THEN rate ELSE 0
           END) as `2018-06-04`
FROM (SELECT ls.*, DATE(ls.issuedDateTime) as date
             (SELECT lr.rate
              FROM lunch_rate lr
              WHERE DATE(lr.created_on) <= DATE(ls.issuedDateTime)
              ORDER BY lr.created_on DESC
              LIMIT 1
             ) as rate
      FROM lunch_status ls
      WHERE DATE(issuedDateTime) BETWEEN '2018-06-01' AND '2018-06-04'        
     ) lr
GROUP BY lr.userId;
请注意其他变化:

午餐价格的子查询不使用MAX。而是使用ORDER BY。 列别名由反勾号包围,而不是单引号。我不赞成这些名字,因为它们需要转义。但如果需要,请使用适当的转义字符。 表具有合理的别名,列名是限定的。 午餐价格的样本数据不够,能否为这4个日期提供适当的数据午餐价格的样本数据不够,能否为这4个日期提供适当的数据