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

时间:2018-05-24 18:42:55

标签: php mysql pdo sql-order-by

示例表格布局: http://rextester.com/QSDQA17146

我不是百分百肯定..但我相信错误源于事情的查询方面......

背景: 我有一个查询..我传递一个数组,用于根据表中数组中的值/字段检索数据。

我最初使用IN()子句..但因为我的数组可以/确实有重复(即:1,2,3,4,2,3,6,7)..我需要返回一行IN()子句中的每个值(即使表中只有1行)..

在这里获得一些帮助之后......我被告知要将此更新为UNION ALL查询..所以我实际上可以为我的数组中的每个项目返回一行(无论它是否重复)

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);

我现在确实为每个项目返回了一行..但是返回的数据并没有遵守传递给查询的数组的原始顺序。

我正在调用函数/查询:

$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代码并按照数组顺序在哪里/哪里改变..它似乎在查询返回部分?

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

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结构..等等..我再次检查数组(我可以发布这个......但我不想阻止对事物顺序的关注); )

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" } 

一切似乎都很好..正确的内容..并纠正原始订单。

然而..当我得到我的查询响应/数据时...顺序不一样。它似乎有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" } } 

1 个答案:

答案 0 :(得分:1)

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

如果我们需要按特定顺序返回的行,我们会在最外面的ORDER BY上提供SELECT

例如,我们可以将seq列列为ORDER BY中的第一个表达式,以便按seq顺序返回行。我们可以向ORDER BY添加其他表达式,以使行的顺序更具确定性(即,当t中有多个行“匹配”来自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的行匹配。规范不清楚除了行的顺序之外,预期从查询返回。)