PHP、PDO & MySQL - 返回的查询顺序不正确

PHP, PDO & MySQL - returned query order not correct

示例 table 布局: http://rextester.com/QSDQA17146

我不是 100% 确定..但我相信错误源于事物的查询方面....

背景: 我有一个查询..我将一个数组传递给它,用于根据 table.

数组中的 value/field 检索数据

我最初使用的是 IN() 子句。但是因为我的数组 can/does 有重复项(即:1、2、3、4、2、3、6、7)。我需要为 IN() 子句中的每个值编辑一行 return(即使 table 中只有 1 行)..

在这里得到一些帮助后..我被告知将其更新为 UNION ALL 查询..所以我实际上可以为我的数组中的每个项目获得一行 returned(不管它是否是是否重复)

SELECT * FROM tablex
WHERE CONCAT(brandname, ' ', dosage) IN (
    'Zyflo CR Extended-release tablet 600 mg',
    ' SEE NOTES BELOW',
    'Zyflo CR Extended-release tablet 600 mg'
) ORDER BY FIELD(
    CONCAT(brandname, ' ', dosage),
    'Zyflo CR Extended-release tablet 600 mg',
    ' SEE NOTES BELOW',
    'Zyflo CR Extended-release tablet 600 mg'
);

所以我尽可能地更新了使用 PDO 和 UNION ALL 调用的东西。

SELECT t.* FROM (
  SELECT 1 as seq,
  'Zyflo CR Extended-release tablet 600 mg' as item
  UNION ALL
  SELECT 2, ' SEE NOTES BELOW '
  UNION ALL
  SELECT 3, 'Zyflo CR Extended-release tablet 600 mg'
) AS inList
INNER JOIN pbaap_drugs AS t ON inList.item = CONCAT(t.brandname, ' ', t.dosage);

我现在为每个项目得到一行 returned.. 但是 returned 数据不符合传递到查询中的数组的原始顺序。

我正在给 function/query 打电话:

$gn_displayList = get_displayList_alt($tablename, $conn, array_values(array_filter($_POST['gn_MedicineSelect'])));//array_filter() added to get count of only non empty indexes (no bloat)

我尝试输出一些 DEBUG 代码并遵循 where/where 数组顺序正在改变.. 它似乎在查询 return 部分?

这是传递给上面函数的数组(已解析):

FILTERED ARRAY CONTENTS: array(3) { [0]=> string(39) "Zyflo CR Extended-release tablet 600 mg" [1]=> string(17) " SEE NOTES BELOW " [2]=> string(39) "Zyflo CR Extended-release tablet 600 mg" }

在我动态构建 UNION ALL 结构等的实际查询函数中。我再次检查数组(我可以 post 这个...但我不想阻止关注事情的顺序);)

array(3) { [0]=> string(39) "Zyflo CR Extended-release tablet 600 mg" [1]=> string(17) " SEE NOTES BELOW " [2]=> string(39) "Zyflo CR Extended-release tablet 600 mg" } 

一切似乎都很好..正确的内容..和正确的原始顺序。

但是..当我收到查询时response/data..顺序不一样。它似乎已经进行了 alpha 排序?

array(3) { [0]=> array(10) { ["id"]=> string(2) "74" ["lastupdated"]=> string(19) "0000-00-00 00:00:00" ["category"]=> string(24) "5-Lipoxygenase Inhibitor" ["brandname"]=> string(32) "Zyflo CR Extended-release tablet" ["genericname"]=> string(8) "zileuton" ["dosage"]=> string(6) "600 mg" ["image"]=> string(43) "Zyflo CR Extended-release tablet 600 mg.jpg" ["zone"]=> string(16) "green,yellow,red" ["menu"]=> string(1) "1" ["active"]=> string(1) "1" } [1]=> array(10) { ["id"]=> string(2) "74" ["lastupdated"]=> string(19) "0000-00-00 00:00:00" ["category"]=> string(24) "5-Lipoxygenase Inhibitor" ["brandname"]=> string(32) "Zyflo CR Extended-release tablet" ["genericname"]=> string(8) "zileuton" ["dosage"]=> string(6) "600 mg" ["image"]=> string(43) "Zyflo CR Extended-release tablet 600 mg.jpg" ["zone"]=> string(16) "green,yellow,red" ["menu"]=> string(1) "1" ["active"]=> string(1) "1" } [2]=> array(10) { ["id"]=> string(2) "78" ["lastupdated"]=> string(19) "0000-00-00 00:00:00" ["category"]=> string(0) "" ["brandname"]=> string(16) " SEE NOTES BELOW" ["genericname"]=> string(0) "" ["dosage"]=> string(0) "" ["image"]=> string(0) "" ["zone"]=> string(16) "green,yellow,red" ["menu"]=> string(1) "1" ["active"]=> string(1) "1" } } 

如果 SELECT 上没有 ORDER BY 子句,MySQL 可以按其选择的任何顺序自由 return 行。此行为符合标准。

如果我们需要按特定顺序排列的行 return,我们会在最外面的 SELECT 上提供一个 ORDER BY

例如,我们可以将 seq 列列为 ORDER BY 中的第一个表达式,以便按 seq 顺序对行进行 return 编辑。我们可以向 ORDER BY 添加额外的表达式,使行的顺序更具确定性(即,当有多行来自 t 时,"match" 一行来自 inList

SELECT t.id
     , t.lastupdated
     , t.category
     , t.brandname
     , t.genericname
     , t.dosage
     , t.image
     , t.zone
     , t.menu
     , t.active
  FROM ( SELECT 1 AS seq, 'Zyflo CR Extended-release tablet 600 mg' AS item 
          UNION ALL
         SELECT 2, ' SEE NOTES BELOW '
          UNION ALL
         SELECT 3, 'Zyflo CR Extended-release tablet 600 mg' 
       ) inList
  JOIN pbaap_drugs t
    ON CONCAT(t.brandname, ' ', t.dosage) = inList.item
 ORDER
    BY inList.seq
     , t.brandname
     , t.dosage
     , ... 

(请注意,t 中与 seq=1 和 seq=3 的行上的 item 匹配的行不会匹配 seq=2 的行。规范不清楚除了行的顺序之外,查询中预期的 return 是什么。)