Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL变量未按预期在case表达式中工作_Mysql_Sql - Fatal编程技术网

MySQL变量未按预期在case表达式中工作

MySQL变量未按预期在case表达式中工作,mysql,sql,Mysql,Sql,下面是我查询的一部分,其中变量@days在CASE表达式中不起作用,而在以前版本的MariaDB中它工作得很好。如果我将DATEDIFF('2018-02-26','2018-02-22')替换案例表达式部分中的@days,它会起作用,但如果我将其分配给变量,为什么它不起作用 SELECT @is_base := 'Yes', @days := DATEDIFF('2018-02-26', '2018-02-22') days, (CASE WHEN (@is_base = 'No' AN

下面是我查询的一部分,其中变量
@days
CASE
表达式中不起作用,而在以前版本的MariaDB中它工作得很好。如果我将
DATEDIFF('2018-02-26','2018-02-22')
替换案例表达式部分中的
@days
,它会起作用,但如果我将其分配给变量,为什么它不起作用

SELECT @is_base := 'Yes', @days := DATEDIFF('2018-02-26', '2018-02-22') days,
(CASE 
  WHEN (@is_base = 'No' AND @days < 7) THEN r.nightly * @days
  WHEN (@is_base = 'No' AND @days >= 7 AND @days < 28) THEN (r.weekly / 7) * @days
  WHEN (@is_base = 'No' AND @days >= 28) THEN (r.monthly / 28) * @days
  ELSE u.base_rate_nightly * @days
END) AS total_price
SELECT@is_base:='Yes',@days:=DATEDIFF('2018-02-26','2018-02-22')天,
(案例
当(@is_base='No'和@days<7)时,则r.夜间*@days
当(@is_base='No'和@days>=7和@days<28)时,则(r.weekly/7)*@days
当(@is_base='No'和@days>=28)时,则(r.monthly/28)*@days
每夜*天的其他基本费率
结束)作为总价
更新以下是完整的查询

`SELECT `u`.`ID`, `u`.`destination`, `u`.`unit_name`, `u`.`base_rate_nightly`, `u`.`lat`, `u`.`lng`, `u`.`number_of_bedrooms`, `u`.`max_guests`, `r`.`ID` as `rate_id`, `r`.`nightly`, `r`.`weekly`, `r`.`monthly`, `i`.`filename`, `t`.`name` as `unit_type`, @days := DATEDIFF('2018-02-26', '2018-02-22') days, `u`.`base_rate_nightly` as `total_price`, 'Yes' is_base, @is_base := if(('2018-02-22' <= r.enddate) and ('2018-02-26' >= r.startdate) or ('2018-02-22' <= r.enddate)  and  (r.startdate <= '2018-02-26'), 'No', 'Yes') as is_base, CASE 
                        WHEN (@is_base = 'No' AND @days < 7) THEN r.nightly * @days
                        WHEN (@is_base = 'No' AND @days >= 7 AND @days < 28) THEN (r.weekly / 7) * @days
                        WHEN (@is_base = 'No' AND @days >= 28) THEN (r.monthly / 28) * @days
                        ELSE u.base_rate_nightly * @days
                    END AS total_price
FROM `vs_units` `u`
LEFT JOIN `vs_unit_images` `i` ON `u`.`ID` = `i`.`ID_unit`
LEFT JOIN `vs_unit_rates` `r` ON `u`.`ID` = `r`.`ID_unit` AND (('2018-02-22' <= r.enddate) and ('2018-02-26' >= r.startdate) or ('2018-02-22' <= r.enddate)  and (`r`.`startdate` <= '2018-02-26'))
LEFT JOIN `vs_unit_types_readonly` `t` ON `t`.`ID` = `u`.`ID_unit_type`
WHERE `u`.`max_guests` >= '1'
AND   (
`u`.`ID` NOT IN(SELECT DISTINCT ID_unit from vs_calendar WHERE ('2018-02-22' <= enddate) and ('2018-02-26' >= `startdate`) or ('2018-02-22' <= `enddate`)  and  (startdate <= '2018-02-26'))
 )
GROUP BY `u`.`ID`
选择'u`.'ID`、'u`.'destination`、'u`.'unit\'name`、'u`.'base\'u rate\'u nightly`、'u`.'lat`、'u`.'lng`、'u`.'number\'u of\'u卧室`、'u`.'max\'u客人`、'r`.'ID`作为'rate\'u ID`、'r`、'r`.'nightly`、'r`.'weekly`、'r`.'weekly`、'r`.'i`.'filename`、't`.'name`作为`.'unit days.'u-Dates:'2018年的日期为'26-02日,','u`.'base_rate_nightly`作为'total_price','Yes'为_base,@is_base:=如果('2018-02-22'=r.startdate)或('2018-02-22'=28),则为(r.monthly/28)*@天
每夜*天的其他基本费率
以总价结束
从'vs_units'`u`
左键连接'vs\u unit\u图像'u'上的'i'。'ID`='i`.'ID\u unit`

左JOIN`vs_unit_rates`r`ON`u`.`ID`=`r`.`ID_unit`和('2018-02-22'=r.startdate)或('2018-02-22'问题不在于
CASE
表达式。问题在于在多列中使用变量。MySQL不保证表达式中变量的赋值顺序

在本例中,您有一个简单的解决方案。只需将逻辑移到
FROM
子句:

SELECT @days as days,
       (CASE WHEN @is_base = 'No' AND @days < 7 THEN r.nightly * @days
             WHEN @is_base = 'No' AND @days >= 7 AND @days < 28 THEN (r.weekly / 7) * @days
             WHEN @is_base = 'No' AND @days >= 28 THEN (r.monthly / 28) * @days
             ELSE u.base_rate_nightly * @days
        END) AS total_price
FROM (SELECT @is_base := 'Yes',
             @days := DATEDIFF('2018-02-26', '2018-02-22')
     ) params;

您正在为变量赋值,并在同一语句中读取它们。不建议这样做

一般来说,除了SET语句之外,您不应该 为用户变量赋值并读取同一变量中的值 声明

将语句放在查询之前:

SET @is_base := 'Yes';
SET @days := DATEDIFF('2018-02-26', '2018-02-22');

SELECT
    @is_base,
    @days AS days,
    CASE
        WHEN (@is_base = 'No' AND @days < 7) THEN r.nightly * @days
        WHEN (@is_base = 'No' AND @days >= 7 AND @days < 28) THEN (r.weekly / 7) * @days
        WHEN (@is_base = 'No' AND @days >= 28) THEN (r.monthly / 28) * @days
        ELSE u.base_rate_nightly * @days
    END AS total_price
FROM r
SET@is_base:=“是”;
设置日期:=DATEDIFF('2018-02-26','2018-02-22');
挑选
@这是我们的基地,
@日复一日,
案例
当(@is_base='No'和@days<7)时,则r.夜间*@days
当(@is_base='No'和@days>=7和@days<28)时,则(r.weekly/7)*@days
当(@is_base='No'和@days>=28)时,则(r.monthly/28)*@days
每夜*天的其他基本费率
以总价结束
从r
至于修改后的查询,我认为您可以简单地将所有变量放在一个派生表中,并将其余的表与之连接:

FROM `vs_units` `u`
INNER JOIN (
    SELECT
        CASE
            WHEN ('2018-02-22' <= r.enddate) and ('2018-02-26' >= r.startdate) or ('2018-02-22' <= r.enddate)  and  (r.startdate <= '2018-02-26') THEN 'No'
            ELSE 'Yes'
        END as is_base,
        DATEDIFF('2018-02-26', '2018-02-22') AS days
) params
LEFT JOIN `vs_unit_images` `i` ON `u`.`ID` = `i`.`ID_unit`
LEFT JOIN `vs_unit_rates` `r` ON `u`.`ID` = `r`.`ID_unit` AND (('2018-02-22' <= r.enddate) and ('2018-02-26' >= r.startdate) or ('2018-02-22' <= r.enddate)  and (`r`.`startdate` <= '2018-02-26'))
LEFT JOIN `vs_unit_types_readonly` `t` ON `t`.`ID` = `u`.`ID_unit_type`
FROM`vs\u units``u`
内连接(
挑选
案例

当('2018-02-22'=r.startdate)或('2018-02-22'感谢您的回答:-)根据@Gordon,“MySQL不保证表达式中变量的赋值顺序”,所以我认为它不会起作用,另一个问题是,我正在使用Codeigniter的查询生成器,所以使用set-things有点棘手,我已经尝试过了,但我失败了。@Muhammad看到了其他答案,第二个选项。这是我通常做的。我正在尝试,但还没有运气,查询非常复杂,让我在问题中发布整个查询。我已经更新了问题,现在我已经发布了整个查询。
FROM `vs_units` `u`
INNER JOIN (
    SELECT
        CASE
            WHEN ('2018-02-22' <= r.enddate) and ('2018-02-26' >= r.startdate) or ('2018-02-22' <= r.enddate)  and  (r.startdate <= '2018-02-26') THEN 'No'
            ELSE 'Yes'
        END as is_base,
        DATEDIFF('2018-02-26', '2018-02-22') AS days
) params
LEFT JOIN `vs_unit_images` `i` ON `u`.`ID` = `i`.`ID_unit`
LEFT JOIN `vs_unit_rates` `r` ON `u`.`ID` = `r`.`ID_unit` AND (('2018-02-22' <= r.enddate) and ('2018-02-26' >= r.startdate) or ('2018-02-22' <= r.enddate)  and (`r`.`startdate` <= '2018-02-26'))
LEFT JOIN `vs_unit_types_readonly` `t` ON `t`.`ID` = `u`.`ID_unit_type`
('2018-02-22' <= enddate) and ('2018-02-26' >= startdate) or ('2018-02-22' <= enddate) and (startdate <= '2018-02-26')
('2018-02-22' <= enddate) and ('2018-02-26' >= startdate)