【问题标题】:SQL query with multiple ORDER BY Field statements - or perhaps a new approach?具有多个 ORDER BY Field 语句的 SQL 查询 - 或者可能是一种新方法?
【发布时间】:2014-04-13 19:28:46
【问题描述】:

我正在尝试构建一个查询,以查找与邮政编码接近/距离内的公司。

现在用户输入邮政编码(通过网络表单)和半径(1、5、10 英里等),我正在使用this PHP 类来查找最近的邮政编码、半径、距离、等(效果很好)。然后我有一个查询,可以找到所有有这些邮政编码的公司并将它们列出来。

我遇到的问题是邮政编码存储在数据库中的三个位置。它们要么存储在公司表中,要么存储在其他两个相关表之一中(下面的简化示例)。而且无论邮政编码字段在哪里,我都无法弄清楚如何按邻近度对结果进行排序。

表格:

公司(表)id、名称、邮编

company_delivery (table) id, company_id (fk), zip

company_other_areas (table) id, company_id (fk), zip

$zip_codes 是从上面提到的邮政编码类中输出的一个 zip 数组,它们在最靠近最远的地方列出:

$zip_code_array = array(
    90210,
    90211,
    90212
)

//* edited - thanks @crafter
$zip_codes = implode(', ', $zip_code_array);

我正在使用的查询

$sql="
SELECT
  company.id, company.name, company.zip, company_delivery.zip, company_other_areas.zip
FROM
  company
LEFT JOIN
  company_delivery ON company.id = company_delivery.company_id
LEFT JOIN
company_other_areas ON company.id = company_other_areas.company_id
WHERE
  company.zip IN($zip_codes) OR company_delivery.zip IN($zip_codes) OR company_other_areas.zip IN($zip_codes)
GROUP BY
  company.id
ORDER BY
  FIELD(company.zip, $zip_codes),
  FIELD(company_delivery.postal_code, $zip_codes)
  FIELD(company_other_areas.postal_code, $zip_codes)
";

我似乎无法弄清楚按邮政编码对公司进行排序,与从邮政编码类返回的顺序相同。 - 通过上述查询,它可以独立地按每个“FIELD”排序。是否可以将数据库中所有返回的邮政编码放入可以排序的合并变量中?

感谢您对此的任何帮助或指点!

【问题讨论】:

  • 您可以使用 UNION stackoverflow.com/questions/3531251/… 合并表
  • 谢谢! - 这似乎是个好主意,但是三个 zip 表都具有相同的优先级。或者,也许我只是不明白?

标签: php mysql sql yii


【解决方案1】:

替换

FIELD(company.zip, $zip_codes),
FIELD(company_delivery.postal_code, $zip_codes)
FIELD(company_other_areas.postal_code, $zip_codes)

COALESCE(
    FIELD(company.zip, $zip_codes),
    FIELD(company_delivery.postal_code, $zip_codes)
    FIELD(company_other_areas.postal_code, $zip_codes)
)

应该做的伎俩。

【讨论】:

  • 感谢您的回复!我尝试按照您的建议使用 COALESCE,但结果仍然有些随机。 (即,邮政编码为 90212 的公司在邮政编码为 90210 的公司之前列出)。有没有办法将三个表结果合并成一个新的临时变量来排序?再次感谢!
  • COALESCE 所做的只是在提供的值中选择第一个非NULL-值。还有什么需要的吗?
【解决方案2】:

我会 COALESCE SELECT 子句中的字段,然后在 order by 子句中按列号排序。像这样:

SELECT company.id, 
       company.name, 
       COALESCE(company.zip, company_delivery.zip, company_other_areas.zip) AS zip_code
  FROM company
  LEFT JOIN company_delivery ON company.id = company_delivery.company_id
  LEFT JOIN company_other_areas ON company.id = company_other_areas.company_id
 WHERE (   company.zip IN($zip_codes) 
        OR company_delivery.zip IN($zip_codes) 
        OR company_other_areas.zip IN($zip_codes)
       )
 GROUP BY company.id
 ORDER BY 3
;

【讨论】:

    【解决方案3】:

    使用联合,将创建一个临时表,其中包含来自三个查询的记录,并且 order by 子句将对记录进行排序,而不考虑查询的顺序。

    【讨论】:

    • 你能给我一个例子,说明使用 UNION 和相关表的查询是什么样子的吗? MySQL 抱怨表没有/不匹配正确的列数。
    【解决方案4】:

    应该是这样的

    SELECT company.name, a.company_id, a.zip FROM ( SELECT id AS company_id, zip FROM company UNION ALL SELECT company.id, zip FROM company_delivery  UNION ALL SELECT company.id, zip FROM company_other_areas ) a JOIN company ON a.company_id = company.id ORDER BY a.zip;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-16
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 2017-07-10
      • 2021-07-20
      • 1970-01-01
      相关资源
      最近更新 更多