我正在开发一个管理事件的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"
有解决方法吗? 非常感谢!
答案 0 :(得分:2)
你也可以通过查询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 的值将如下(例如数据):
SELECT 318 AS id UNION ALL
SELECT 185 AS id UNION ALL
SELECT 180 AS id UNION ALL
SELECT 377 AS id
$ events_titles 的值将是一个数组,每个事件都有一个条目,无论它是否匹配。所以对于你给出的例子,你会得到这个结果:
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
。如果另外您要删除null
条目而不更改数组中的索引(0 ... 3),请执行以下操作:
$event_titles = array_filter($event_titles, function ($title) { return $title; });
这将给你(在例子中):
array(
0 => array("title" => "title for 318"),
3 => array("title" => "title for 377")
)
答案 1 :(得分:1)
使用in子句似乎不可能,但您可以使用union form 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"
答案 2 :(得分:0)
不,没有办法。 mysql-query返回的数组与您为查询提供的implode-array无关。可能有选项可以实现这一点(创建一个临时表,用键填充它,从表连接到事件表的左连接),但请不要这样做,因为这是不好的做法和坚果KISS(保持简单,愚蠢)。
简单的问题是,你为什么要这样做?