• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

248
Views
¿Cómo especificar un ORDER BY a partir de comparaciones y verificaciones nulas en MySQL?

Tengo dos tablas feed_old (datos predeterminados) y feed_new (datos nuevos) donde el trabajo cron se ejecutará todos los días y actualizará SOLO la tabla feed_new con la información actual

trabajo cron

 $url = "localhost/test.xml"; $xml = simplexml_load_file($url); $this->db->query("TRUNCATE TABLE feed_new"); $date = date('Ymd H:i:s'); foreach($xml->Product as $item) { $data = array( 'product_code' => $item->ProductCode, 'name' => $item->Name, 'price' => $item->RetailCurrentPrice, 'stock' => (int)$item->Stock, 'manufacture' => '1', 'date_updated' => $date ); $update_status = $this->model_price->check_price($data); }

Modelo

 public function check_price($data) { if($data) { $insert = $this->db->insert('feed_new', $data); return ($insert == true) ? true : false; } }

Desde aqui todo funcionando bien

El problema surge cuando comparo feed_new vs feed_old y obtengo los cambios y muestro todos los registros

Después de comparar feed_new vs feed_old, me gustaría extraer todos los registros de ambas tablas y ordenarlos por niveles.

Nivel 1: si los productos tienen un precio diferente feed_new.price <> feed_old.price

Nivel 2: si el producto de feed_old no existe en feed_new (eso significa que el producto ya no es compatible)

Nivel 3: si el producto de feed_new no existe en feed_old (eso significa que el producto es nuevo)

Nivel 4 - resto de resultados

Consulta de comparación

 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 FROM feed_old fo LEFT JOIN feed_new fn ON fo.product_code = fn.product_code UNION ALL 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 FROM feed_old fo RIGHT JOIN feed_new fn ON fn.product_code = fo.product_code 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

El problema es que el Nivel - 3 siempre se muestra en el último registro, es decir, después del nivel - 4 en mi ejemplo de trabajo a continuación, puede ver name_new -> test3 está en la parte inferior de la tabla cuando debería estar en la tercera posición.

¿Cómo puedo ordenarlos por niveles superiores?

Ejemplo de trabajo

about 3 years ago · Santiago Trujillo
2 answers
Answer question

0

COALESCE no parece la función más apropiada para este orden ya que solo devuelve el primer valor que no es NULL , lo cual no es intuitivo cuando se hacen comparaciones donde los operandos podrían ser NULL .

Sugeriría usar CASE en su lugar con un valor entero ficticio para el nivel, algo como esto:

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

Vea esta demostración de SQLFiddle: http://sqlfiddle.com/#!9/57c8eb3/6 .

about 3 years ago · Santiago Trujillo Report

0

Puede escribir una mejor solución usando IFNULL, CASE WHEN y UNION.

Solución: http://sqlfiddle.com/#!9/57c8eb3/21

 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, (case when (IFNULL(fn.product_code,'X') != 'X' and fo.price != fn.price) then 'Level1' when IFNULL(fn.product_code,'X') = 'X' then 'Level2' else 'Level4' end) as Ordering_level FROM feed_old fo LEFT JOIN feed_new fn ON fo.product_code = fn.product_code UNION 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, (case when (IFNULL(fo.product_code,'X') != 'X' and fo.price != fn.price) then 'Level1' when IFNULL(fo.product_code,'X') = 'X' then 'Level3' else 'Level4' end) as Ordering_level FROM feed_old fo RIGHT JOIN feed_new fn ON fn.product_code = fo.product_code order by ordering_level
about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error