I was building an “image wall” for a WordPress site, consisting of all images attached to posts, and had to pull out all image attachments. It also should not pull in attachments to posts that are not yet published, and it needs to be a single query to allow for pagination. Here is the result:
global $wpdb;
$posts_per_page = 10;
$offset = 0;
$attachment_posts = $wpdb->get_results("
SELECT
ID,
post_parent as parent,
post_status,
(SELECT post_status FROM {$wpdb->prefix}posts wp2 WHERE wp2.ID = wp.post_parent AND (post_type = 'post' OR post_type = 'page')) as parent_status,
(SELECT post_date FROM {$wpdb->prefix}posts wp3 WHERE wp3.ID = wp.post_parent AND (post_type = 'post' OR post_type = 'page')) as parent_date
FROM {$wpdb->prefix}posts wp
WHERE post_type = 'attachment'
AND post_status = 'inherit'
AND post_parent <> 0
HAVING parent_status = 'publish'
ORDER BY parent_date DESC
LIMIT {$posts_per_page} OFFSET {$offset};",
ARRAY_A);
foreach($attachment_posts as $attachment_post) {
//Loop over attachments.
}
Additional reading
StackOverflow post