我需要按传入的数字或另一列对 MYSQL 结果进行排序

I need to sort MYSQL results by a number passed in OR another column

这是我的 table 和我的 select 声明: SQLFiddle 我想按 job_id 分组,然后按传入的数字对其进行排序(在本例中,数字为 2) 如果没有匹配项,则显示默认标记为 true 的结果 如果 none 标记为真,则按 production_days DESC

排序

最终结果应该是:

所有职位都显示 production_days = 2 的列,但没有匹配列的 103 除外,这是按 is_default DESC

排序的

我试过了

SELECT *, CASE production_days 
WHEN 2 THEN 0 
WHEN is_default = 1 THEN 1 
ELSE 2 
END as sort
FROM `jobs` GROUP BY JOB_ID ORDER BY JOB_ID, sort

编辑: 期望的结果是:具有唯一 job_id 且在 production_days 列中具有编号 2 的行,如果 job_idjob_id 中没有 2列,然后我在 is_default 列中寻找 1。我不关心结果是如何实现的,但我想在一个 select 语句中完成。 谢谢

我将按我的理解重新表述:您想首先对 production_days = 2 的作业进行排序,然后对 is_default 为真的作业进行排序,然后对其他作业进行排序。

为此,我首先将查询分解为三组并将它们放在一起。我从获取 production_days 中值为 2 的那些开始,这是最简单的。我在最后硬编码了一个 0 来证明这是第一组:

SELECT j.*, 0
FROM jobs j
WHERE j.production_days = 2;

然后,我找到 is_default = 1 而 production_days 不为 2 的工作,如下所示:

SELECT j.*, 1
FROM jobs j
WHERE j.is_default = 1 
AND j.job_id NOT IN (
  SELECT job_id
  FROM jobs
  WHERE production_days = 2);

对于最后一组,您只需检查不在前面两个列表中的作业。这实际上稍微简化了它,因为您可以将要求缩小到 production_days 为 2 或 is_default = 1:

的项目
SELECT j.*, 2
FROM jobs j
WHERE j.job_id NOT IN(
  SELECT job_id
  FROM jobs
  WHERE is_default = 1
  OR production_days = 2);

最后一步是对结果进行合并和排序。您可以使用 UNION,然后像这样按 sortPosition 排序:

SELECT j.*, 0 AS sortPosition
FROM jobs j
WHERE j.production_days = 2
UNION
SELECT j.*, 1 AS sortPosition
FROM jobs j
WHERE j.is_default = 1 
AND j.job_id NOT IN (
  SELECT job_id
  FROM jobs
  WHERE production_days = 2)
UNION
SELECT j.*, 2 AS sortPosition
FROM jobs j
WHERE j.job_id NOT IN(
  SELECT job_id
  FROM jobs
  WHERE is_default = 1
  OR production_days = 2)
ORDER BY job_id, sortPosition;

这是一个 SQL Fiddle 示例。

这是一个 'old school' 解决方案...(尽管它对您的数据集做出了某些可能不正确的假设)

SELECT j.*
  FROM jobs j
 JOIN 
    ( SELECT id,job_id, 1 rank FROM jobs WHERE production_days = 2
        UNION
       SELECT id,job_id, 2  FROM jobs WHERE is_default = 1
     ) a
    ON a.id = j.id
  LEFT
  JOIN 
     ( SELECT id,job_id, 1 rank FROM jobs WHERE production_days = 2
        UNION
       SELECT id,job_id, 2  FROM jobs WHERE is_default = 1
     ) b
    ON b.job_id = a.job_id
   AND b.rank < a.rank
 WHERE b.id IS NULL