Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.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/5/sql/87.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 SQL查询联合最佳实践_Mysql_Sql - Fatal编程技术网

Mysql SQL查询联合最佳实践

Mysql SQL查询联合最佳实践,mysql,sql,Mysql,Sql,我试图在从表中提取数据时对其进行分类。数据在每一行中都有一个历史记录,该历史记录是通过valid_from和valid_to date字段保存的 我想提取数据,并对其进行如下限定: NEW => WHERE CURRENT_DATE BETWEEN valid_from AND (valid_from + 1 MOTNH) CURRENT => WHERE CURRENT_DATE > (valid_from + 1 MOTNH) RETIRED => the rest

我试图在从表中提取数据时对其进行分类。数据在每一行中都有一个历史记录,该历史记录是通过valid_from和valid_to date字段保存的

我想提取数据,并对其进行如下限定:

NEW => WHERE CURRENT_DATE BETWEEN valid_from AND (valid_from + 1 MOTNH)
CURRENT => WHERE CURRENT_DATE > (valid_from + 1 MOTNH)
RETIRED => the rest of the rows, so the "dish_id" items not in the tables above, BUT 
           returning the values from the row containing MAX(valid_to) date.
我这样做是最好/更有效的方式吗?提前谢谢

SELECT
    menu_table.dish_id,
    menu_table.dish_title,
    menu_table.marketing_desc,
    menu_table_status.rrp_inc_gst,
    menu_table_status.lowest_rrp,
    menu_table_status.highest_rrp,
    'n' as status
FROM 
    menu_table,
    menu_table_status
WHERE
    CURRENT_DATE BETWEEN menu_table_status.valid_from_date AND DATE_ADD(menu_table_status.valid_from_date, INTERVAL 1 MONTH) 
    AND CURRENT_DATE < menu_table_status.valid_to_date
    AND menu_table.dish_id = menu_table_status.dish_id
UNION
SELECT
    menu_table.dish_id,
    menu_table.dish_title,
    menu_table.marketing_desc,
    menu_table_status.rrp_inc_gst,
    menu_table_status.lowest_rrp,
    menu_table_status.highest_rrp,
    'c' as status
FROM 
    menu_table,
    menu_table_status
WHERE
    CURRENT_DATE > DATE_ADD(menu_table_status.valid_from_date, INTERVAL 1 MONTH) 
    AND CURRENT_DATE < menu_table_status.valid_to_date
    AND menu_table.dish_id = menu_table_status.dish_id              
UNION
SELECT
    menu_table.dish_id,
    menu_table.dish_title,
    menu_table.marketing_desc,
    menu_table_status.rrp_inc_gst,
    menu_table_status.lowest_rrp,
    menu_table_status.highest_rrp,
    'r' as status
FROM 
    menu_table,
    menu_table_status
WHERE
    menu_table_status.valid_to_date
    AND menu_table.dish_id NOT IN (SELECT inside_table1.dish_id
                       FROM menu_table_status AS inside_table1
                       WHERE CURRENT_DATE BETWEEN inside_table1.valid_from_date 
                                                          AND inside_table1.valid_to_date)
    AND menu_table_status.valid_to_date = (SELECT MAX(inside_table2.valid_to_date)
                           FROM menu_table_status AS inside_table2
                           WHERE inside_table2.dish_id = menu_table_status.dish_id)
    AND menu_table.dish_id = menu_table_status.dish_id

如果不仔细查看,您肯定会在最后一个where子句中混淆日期。不管怎样,你的陈述太复杂了。只需选择您想要执行的所有记录,并查看每个记录的日期,即可确定状态:

SELECT
  menu_table.dish_id,
  menu_table.dish_title,
  menu_table.marketing_desc,
  menu_table_status.rrp_inc_gst,
  menu_table_status.lowest_rrp,
  menu_table_status.highest_rrp,
  CASE 
    WHEN
      CURRENT_DATE BETWEEN menu_table_status.valid_from_date AND DATE_ADD(menu_table_status.valid_from_date, INTERVAL 1 MONTH) 
      AND CURRENT_DATE < menu_table_status.valid_to_date
    THEN 'n' 
    WHEN
      CURRENT_DATE > DATE_ADD(menu_table_status.valid_from_date, INTERVAL 1 MONTH) 
      AND CURRENT_DATE < menu_table_status.valid_to_date
    THEN 'c'
    ELSE 'r'
  END as status
FROM menu_table
INNER JOIN menu_table_status ON menu_table.dish_id = menu_table_status.dish_id;
顺便说一句:请不要使用旧的联接语法,在这里列出所有以逗号分隔的表。它很容易出错,这就是为什么在1992年有了新的语法

编辑:我发现了你的错误。您不必检查当前日期
还有一句话:当联合不同的集合时,您的集合是由于不同的状态字母,请使用UNION ALL,而不是UNION。UNION用于删除重复项。当您知道没有重复记录时,为什么让dbms检查您的所有记录?

如果您不需要一次性执行此操作,我建议将第一步提取到一个临时表中,然后将第二步定义为dish\u id与该临时表的左连接,其中dish\u id为空:

CREATE TEMPORARY TABLE step1 AS (
SELECT
    mt.dish_id,
    mt.dish_title,
    mt.marketing_desc,
    mts.rrp_inc_gst,
    mts.lowest_rrp,
    mts.highest_rrp,
    (
        if(CURRENT_DATE<DATE_ADD(mts.valid_from_date, INTERVAL 1 MONTH),
           'n', 'c')
    ) as status
FROM 
    menu_table mt 
    JOIN menu_table_status mts ON mt.dish_id=mts.dish_id 
    WHERE CURRENT_DATE BETWEEN mts.valid_from_date AND mts.valid_to_date-1
);

SELECT step1.*
UNION
SELECT
    mt.dish_id,
    mt.dish_title,
    mt.marketing_desc,
    mts.rrp_inc_gst,
    mts.lowest_rrp,
    mts.highest_rrp,
    'r' as status
FROM
    menu_table mt 
    LEFT JOIN step1 s1 on s1.dish_id=mt.dish_id WHERE s1.dish_id is NULL
    JOIN menu_table_status mts ON mt.dish_id=mts.dish_id;

嗨,Thorsten,谢谢你的回复!1992年是我最后一次在IBM大型机上使用SQL!我喜欢您的方法,但是您的ELSE r片段是否会导致返回所有其他行,其中包括不满足前两个CASE语句的dish_id的多行?尽管如此,我还是尝试运行它,但由于表名后面的逗号,我在内部JOIN语句中遇到了语法错误!您好,Thornstem,我已经添加了“按菜单点菜”\u table.dish\u title ASC以按字母顺序点菜,但点菜不起作用。我错过了什么?再次感谢!我去掉了逗号。抱歉,这是一个剪切粘贴错误。命令应该有效;我看没有理由不应该。谢谢托尔斯滕,你帮了我很多忙!要完成查询,我需要将GROUP BY menu\u DISKS\u status.dish\u id HAVING MAXmenu\u DISKS\u status.valid\u添加到您的建议中,以获取“r”行的最新条目。再次感谢!