consulta orden sólo por un campo específico, si todos los valores de conjunto de resultados son NULL

Dennis:

Estoy construyendo un sistema de control de versiones de documentos personalizados en mi página web.

Para esto, tengo 2 mesas " vrm_document" y " vrm_document_active_document". La primera tabla contiene todos los documentos en mi sitio web, mientras que la segunda mesa me dice que el documento es la versión activa de la que el usuario, por lo que la segunda tabla contiene el vrm_document_idcampo y un user_idcampo. Documentos activos se indican con el parent_vrm_document_idser no es NULL.

Tengo 2 tipos de documentos:

  • documentos por defecto
  • Los documentos cargados por los propios usuarios

Cada documento que se carga contiene versiones, y min. 1 y max. 1 versión tiene que ser activa en todo momento para el usuario. Así, la segunda tabla vrm_document_active_documentcontendrá siempre la vrm_document_idcombina con la user_idde los documentos cargados por el propio usuario.

Sin embargo, el problema reside en el hecho de que los documentos son documentos predeterminados que son proporcionados por mi página web y será siempre al alcance de todos. Cuando un usuario no tiene su propia versión de un documento predeterminado, el documento predeterminado se convertirá en la versión activa para ese usuario por defecto. Esto está implicado. Para los documentos activos que no inserte filas de la vrm_document_active_documenttabla. Esto significa que si no hay versiones de un documento predeterminado para el usuario activo, el documento predeterminado se convierte en la versión activa por defecto para ese usuario.

Cuando se visualizan los documentos con sus versiones para el usuario, quiero mostrar todas las versiones en una lista bajo la otra, en la que aparece por primera vez la versión activa, y luego los otros están ordenadas en la última hora de modificación.

La siguiente consulta me da los resultados correctos para los documentos que no son documentos por defecto:

SELECT vd.*
FROM `vrm_document` AS `vd`
LEFT JOIN vrm_document_active_document AS vdad ON (vd.vrm_document_id = vdad.vrm_document_id AND vd.user_id = vdad.user_id)
WHERE ((`vd`.`parent_vrm_document_id` = 1 AND `vd`.`user_id` IN (2,18,21)) OR (`vd`.`vrm_document_id` = 1  ) ) 
ORDER BY vdad.vrm_document_id DESC, vd.timestamp_modified_utc DESC

Sin embargo, como se puede ver a partir de la consulta, si imaginamos que el documento de identificación 1 al ser un documento por defecto, todos los campos de la vrm_document_active_documenttabla contendrá NULL, y por lo tanto se va a clasificar en base a la hora de modificación.

El siguiente es (en pseudo-código) lo que necesito para lograr, es esto posible utilizando SQL MariaDB?

ORDER BY:

  • si todos los valores == NULL entonces el valor con default_document es primero, para luego por modified_utc
  • Para lo demás por modified_utc

DB violín: https://www.db-fiddle.com/f/71TUvdxFgFLhdncgo4BRre/1

EDIT: DB violín añadió

Louis Arpad:

En MariaDB usted tiene la IFNULL función y se puede usar como

ifnull(expr1, expr2)

que dice efectivamente:

expr1 evaluar y si es nulo, a continuación, evaluar expr2

Si entiendo bien su problema, entonces su apariencia solución como

order by ifnull(vdad.vrm_document_id, ifnull(vd.timestamp_modified_utc, someothervalue)) desc

En la cláusula anterior someothervalue representa cualquier campo que es posible que desee defecto. Los criterios deseables era claro para mí. Sin embargo, si desea que el documento predeterminado para ser los primeros criterios, a continuación,

ORDER BY dv.is_default_document desc, vdad.vrm_document_id DESC, vd.timestamp_modified_utc DESC

o, si se quiere que eso sea el último de criterios, a continuación,

ORDER BY vdad.vrm_document_id DESC, vd.timestamp_modified_utc DESC, dv.is_default_document desc

EDITAR

SELECT vdad.*, vd.*
FROM `vrm_document` AS `vd`
LEFT JOIN vrm_document_active_document AS vdad ON (vd.vrm_document_id = vdad.vrm_document_id AND vd.user_id = vdad.user_id)
WHERE ((`vd`.`parent_vrm_document_id` = 1 AND `vd`.`user_id` IN (2,18,21)) OR (`vd`.`vrm_document_id` = 1  ) ) 
ORDER BY 
CASE not exists (
    SELECT 1 as cnt
    FROM `vrm_document` AS `vd2`
    LEFT JOIN vrm_document_active_document AS vdad2 ON (vd2.vrm_document_id = vdad2.vrm_document_id AND vd2.user_id = vdad2.user_id)
    WHERE ((`vd2`.`parent_vrm_document_id` = 1 AND `vd2`.`user_id` IN (2,18,21)) OR (`vd2`.`vrm_document_id` = 1  ) ) 
    AND not ((vdad2.vrm_document_id is null) AND (vdad2.user_id))
)
WHEN 1 THEN vd.vrm_document_id
ELSE 0 END,
vdad.vrm_document_id DESC, 
vd.timestamp_modified_utc DESC

La consulta anterior usos de casos y cuando-else-end para comprobar la existencia de algunos registros. No está claro para mí lo que debería ser el criterio exacto, pero, aunque el ejemplo anterior no es su coincidencia exacta, entonces se puede sustituir

AND not ((vdad2.vrm_document_id is null) AND (vdad2.user_id))

a lo que necesita y debería funcionar.

Edit2

La consulta actual ordena por los dos criterios en la cuestión de forma predeterminada, pero si las dos primeras columnas son nulos, entonces el primer elemento será el documento predeterminado:

SELECT vdad.*, vd.*
FROM `vrm_document` AS `vd`
LEFT JOIN vrm_document_active_document AS vdad ON (vd.vrm_document_id = vdad.vrm_document_id AND vd.user_id = vdad.user_id)
WHERE ((`vd`.`parent_vrm_document_id` = 1 AND `vd`.`user_id` IN (2,18,21)) OR (`vd`.`vrm_document_id` = 1  ) ) 
ORDER BY 
CASE not exists (
    SELECT 1 as cnt
    FROM `vrm_document` AS `vd2`
    LEFT JOIN vrm_document_active_document AS vdad2 ON (vd2.vrm_document_id = vdad2.vrm_document_id AND vd2.user_id = vdad2.user_id)
    WHERE ((`vd2`.`parent_vrm_document_id` = 1 AND `vd2`.`user_id` IN (2,18,21)) OR (`vd2`.`vrm_document_id` = 1  ) ) 
    AND not ((vdad2.vrm_document_id is null) AND (vdad2.user_id))
)
WHEN 1 THEN vd.is_default_document
ELSE 0 END desc,
vdad.vrm_document_id DESC, 
vd.timestamp_modified_utc DESC

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=408362&siteId=1
Recomendado
Clasificación