如何在mysql中通过比较和空检查指定order by?

h9vpoimq  于 2021-08-01  发布在  Java
关注(0)|答案(2)|浏览(465)

我有两个表feed_old(默认数据)和feed_new(新数据),cron作业将每天运行,并且只使用当前信息更新feed_new表
定时任务

  1. $url = "localhost/test.xml";
  2. $xml = simplexml_load_file($url);
  3. $this->db->query("TRUNCATE TABLE feed_new");
  4. $date = date('Y-m-d H:i:s');
  5. foreach($xml->Product as $item)
  6. {
  7. $data = array(
  8. 'product_code' => $item->ProductCode,
  9. 'name' => $item->Name,
  10. 'price' => $item->RetailCurrentPrice,
  11. 'stock' => (int)$item->Stock,
  12. 'manufacture' => '1',
  13. 'date_updated' => $date
  14. );
  15. $update_status = $this->model_price->check_price($data);
  16. }

模型

  1. public function check_price($data)
  2. {
  3. if($data) {
  4. $insert = $this->db->insert('feed_new', $data);
  5. return ($insert == true) ? true : false;
  6. }
  7. }

因为这里一切正常
当我比较feed\u new和feed\u old时,问题来了,得到了什么变化,并显示了所有记录
在比较feed\u new和feed\u old之后,我想从两个表中提取所有记录,并按级别对它们进行排序
第1级-如果产品有不同的价格feed\u new.price<>feed\u old.price
2级-如果feed\u old的产品在feed\u new中不存在(这意味着不再支持产品)
第3级-如果feed\u new的产品在feed\u old中不存在(这意味着产品是新的)
4级-剩余结果
比较查询

  1. SELECT fn.name AS name_new, fo.date_updated, fo.id, fo.name,fo.price,fo.product_code, fn.product_code AS product_code_new, fo.stock, fn.price AS price_new, fn.stock AS stock_new, fn.date_updated AS date_updated_new
  2. FROM feed_old fo
  3. LEFT JOIN feed_new fn ON fo.product_code = fn.product_code
  4. UNION ALL
  5. SELECT fn.name AS name_new, fo.date_updated, fo.id, fo.name,fo.price,fo.product_code, fn.product_code AS product_code_new, fo.stock, fn.price AS price_new, fn.stock AS stock_new, fn.date_updated AS date_updated_new
  6. FROM feed_old fo
  7. RIGHT JOIN feed_new fn ON fn.product_code = fo.product_code
  8. WHERE fo.product_code IS NULL OR fn.name IS NULL ORDER BY COALESCE(price <> price_new, name_new is NULL, product_code IS NULL) DESC

问题是level-3总是显示在最后一条记录上,我的意思是在我下面的工作示例中level-4之后,您可以看到name\u new->test3位于表的底部,此时应该位于第3位
我怎样才能按上面的级别订购
工作示例

ih99xse1

ih99xse11#

COALESCE 似乎不是最适合这种排序的函数,因为它只返回第一个非- NULL 值,这在比较操作数可能是 NULL .
建议使用 CASE 而是使用一个虚拟整数值作为级别-类似于:

  1. ORDER BY CASE WHEN price_new IS NOT NULL AND price_new <> price THEN 1
  2. WHEN price_new IS NULL THEN 2
  3. WHEN price IS NULL THEN 3
  4. ELSE 4
  5. END

请看这个sqlfiddle演示:http://sqlfiddle.com/#!9/57c8eb3/6。

rhfm7lfc

rhfm7lfc2#

可以使用ifnull、case-when和union编写更好的解决方案。
解决方案-http://sqlfiddle.com/#!9/57c8eb3/21号

  1. SELECT fn.name AS name_new, fo.date_updated, fo.id, fo.name,fo.price,
  2. fo.product_code, fn.product_code AS product_code_new, fo.stock, fn.price AS price_new,
  3. fn.stock AS stock_new, fn.date_updated AS date_updated_new,
  4. (case when (IFNULL(fn.product_code,'X') != 'X' and fo.price != fn.price)
  5. then 'Level1'
  6. when IFNULL(fn.product_code,'X') = 'X' then 'Level2'
  7. else 'Level4' end) as Ordering_level
  8. FROM feed_old fo LEFT JOIN feed_new fn
  9. ON fo.product_code = fn.product_code
  10. UNION
  11. SELECT fn.name AS name_new, fo.date_updated, fo.id, fo.name,fo.price,
  12. fo.product_code, fn.product_code AS product_code_new, fo.stock,
  13. fn.price AS price_new, fn.stock AS stock_new, fn.date_updated AS date_updated_new,
  14. (case when (IFNULL(fo.product_code,'X') != 'X' and fo.price != fn.price)
  15. then 'Level1'
  16. when IFNULL(fo.product_code,'X') = 'X' then 'Level3'
  17. else 'Level4' end) as Ordering_level
  18. FROM feed_old fo RIGHT JOIN feed_new fn
  19. ON fn.product_code = fo.product_code
  20. order by ordering_level
展开查看全部

相关问题