我正在wordpress上开发一个管理事件的网站。
问题是,我需要在一个查询中从相应的ID中获取一些事件标题名称。我正在尝试从一个MYSQL查询中获得多行,使用"WHERE IN ({$IDs})
":可以很好地工作
$events_implode = implode(',',$events);
$events_titles = $wpdb->get_results("SELECT `title` FROM `wp_events` WHERE `id` in ({$events_implode}) ORDER BY FIELD(id,{$events_implode}",ARRAY_A);
但是,如果在查询中找不到$ID之一,我需要它返回一个值/字符串,而不是什么都不返回。
示例:如果$events_implode
类似于:318,185,180,377
,并且ID为180&185不存在(例如被删除),我取回318的事件标题;仅377:
Array
(
[0] => Array
(
[title] => Title 1
)
[1] => Array
(
[title] => Title 4
)
)
而我需要它来返回类似的东西:
Array
(
[0] => Array
(
[title] => Title 1
)
[3] => Array
(
[title] => Title 4
)
)
我试过IFNULL:
$events_titles = $wpdb->get_results("SELECT IFNULL( (SELECT `title` FROM `wp_events` WHERE `id` in ({$events_implode}) ORDER BY FIELD(id,{$events_implode}) ),'not found')",ARRAY_A);
但是由于查询返回了不止一行,我得到了错误消息:
"mysqli_query(): (21000/1242): Subquery returns more than 1 row"
有解决办法吗?非常感谢!
您可以通过查询id而不仅仅是标题来实现这一点:
SELECT id, title FROM ... etc
然后你的结果数组会像这样(对于示例数据)
array(
0 => array("id" => 318, "title" => "title for 318"),
1 => array("id" => 377, "title" => "title for 377")
)
但在$events数组的帮助下,这可以转换为您需要的内容:
foreach($event_titles as $row) {
$hash[array_search($row['id'], $events)] = $row['title'];
};
$events_titles = $hash;
现在数组看起来是这样的(对于示例数据):
array(
0 => array("title" => "title for 318"),
3 => array("title" => "title for 377")
)
注意:这种转换也可以在没有显式循环的情况下完成:
$ids = array_intersect($events, array_column($event_titles, 'id'));
$event_titles = array_combine(array_keys($ids), array_column($event_titles, 'title'));
备选方案
以上可能是适合您的情况的最佳解决方案,但您也可以动态构建查询以实现这一点:
$subsql = implode(
' UNION ALL ',
array_map(function ($event) { return "SELECT $event AS id"; }, $events)
);
$sql = "SELECT wp_events.title
FROM ($subsql) AS eid
LEFT JOIN wp_events ON wp_events.id = eid.id
ORDER BY eid.id";
$events_titles = $wpdb->get_results($sql, ARRAY_A);
$subsql的值如下(例如data):
SELECT 318 AS id UNION ALL
SELECT 185 AS id UNION ALL
SELECT 180 AS id UNION ALL
SELECT 377 AS id
$events_title的值将是一个数组,每个事件都有一个条目,无论它是否匹配。因此,对于你给出的例子,你会得到这样的结果:
array(
0 => array("title" => "title for 318"),
1 => array("title" => null), // because no match with 185
2 => array("title" => null), // because no match with 180
3 => array("title" => "title for 377")
)
所以您现在可以测试null
。如果您还想在不更改数组中的索引(0…3)的情况下删除null
条目,请执行以下操作:
$event_titles = array_filter($event_titles, function ($title) { return $title; });
这将给您(在示例中):
array(
0 => array("title" => "title for 318"),
3 => array("title" => "title for 377")
)
使用in子句似乎是不可能的,但您可以使用并集形式的dual 构建一个dinamic查询
"SELECT t.index, a.`title`
FROM `wp_events` as a
INNER JOIN ( select 1 as index , 318 as id
from dual
union
select 2, 185
from dual
union
select 3, 180
from dual
union
select 4, 377
from dual
) t on t.id = b.id
ORDER BY t.index"
不,没有办法。mysql查询返回的数组与您提供给查询的内爆数组无关。可能有一些选项可以实现这一点(创建一个临时表,用键填充它,从该表向左联接到事件表),但请不要这样做,因为这是一种糟糕的做法,而且会破坏KISS(保持简单,愚蠢)。
简单的问题是,你为什么要这么做?