简体   繁体   中英

combining 3 queries into one array

Is there a better way to do this? I've got 3 different queries and want to put them all into one array. Since I can't just order them exactly the way I want straight from the query I'm having to do it in 3 separate queries (unless you know of a way to do it IN the query).

Then I'm having to create separate temporary arrays just so I can do a foreach loop to use the array_push() function. Surely there's a much better way than this lol.

$sql = "SELECT prayers.*
    FROM prayers 
    LEFT JOIN prayed_for USING (postid) 
    WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and 
    (
        (priority = 'emergency' and date > DATE_SUB(NOW(), INTERVAL 20 DAY)) 
    or 
        (priority = 'urgent' and date > DATE_SUB(NOW(), INTERVAL 40 DAY))
    ) 
    ORDER BY priority DESC, prayers.date DESC";

    $sql2 = "SELECT prayers.*
    FROM prayers 
    LEFT JOIN prayed_for USING (postid) 
    WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and priority = 'normal' 
    and date > DATE_SUB(NOW(), INTERVAL 60 DAY)
    ORDER BY prayers.date DESC";

    $sql3 = "SELECT prayers.*
    FROM prayers 
    LEFT JOIN prayed_for USING (postid) 
    WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and priority = 'long_term' 
    ORDER BY prayers.date DESC";

    $_SESSION['aprayers'] = send_query($sql);
    $rows2 = array();
    $rows2 = send_query($sql2);
    foreach ($rows2 as $row) {
        array_push($_SESSION['aprayers'],$row);
    }
    $rows3 = array();
    $rows3 = send_query($sql3);
    foreach ($rows3 as $row) {
        array_push($_SESSION['aprayers'],$row);
    }

I believe you should be able to do this in one query without using UNION by combining your criteria and using a CASE to sort the priority. I'm really not sure how the performance of this would compare with the UNION solutions, but it removes some redundancy in the code, for what it's worth.

$sql = "SELECT prayers.*
    FROM prayers 
    LEFT JOIN prayed_for USING (postid) 
    WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and 
    (
        (priority = 'emergency' and date > DATE_SUB(NOW(), INTERVAL 20 DAY)) 
    or 
        (priority = 'urgent' and date > DATE_SUB(NOW(), INTERVAL 40 DAY))
    or
        (priority = 'normal' and date > DATE_SUB(NOW(), INTERVAL 60 DAY))
    or
        priority = 'long_term'     
    ) 
    ORDER BY 
    CASE priority 
        WHEN 'emergency' THEN 1 
        WHEN 'urgent' THEN 2
        WHEN 'normal' THEN 3 
        WHEN 'long_term' THEN 4
    END, prayers.date DESC";

$sql_queries = array($sql1, $sql2, $sql3);
$_SESSION['aprayers'] = array();
foreach($sql_queries as $sql_query)
{
  $_SESSION['aprayers'] = array_merge($_SESSION['aprayers'], send_query($sql_query));
}

You can combine them into one by using the UNION syntax.

https://dev.mysql.com/doc/refman/5.0/en/union.html

Example (updated):

(SELECT prayers.*, 1 as order
  FROM prayers AS p
  LEFT JOIN prayed_for AS f USING (postid) 
  WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and 
    (
      (priority = 'emergency' and date > DATE_SUB(NOW(), INTERVAL 20 DAY)) 
    or 
      (priority = 'urgent' and date > DATE_SUB(NOW(), INTERVAL 40 DAY))
    ) 
) UNION (
SELECT prayers.*, 2 as order
  FROM prayers 
  LEFT JOIN prayed_for USING (postid) 
  WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and priority = 'normal' 
    and date > DATE_SUB(NOW(), INTERVAL 60 DAY)
) UNION (
SELECT prayers.*, 3 as order
  FROM prayers 
  LEFT JOIN prayed_for USING (postid) 
  WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
    and prayers.type = 'prayer' 
    and prayers.privacy != 'hidden'
    and priority = 'long_term' 
) ORDER BY order, priority, p.date

Here is the one query for all:

SELECT prayers.*
FROM prayers 
LEFT JOIN prayed_for USING (postid) 
WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
and prayers.type = 'prayer' 
and prayers.privacy != 'hidden'
and 
(
    (priority = 'emergency' and date > DATE_SUB(NOW(), INTERVAL 20 DAY)) 
or 
    (priority = 'urgent' and date > DATE_SUB(NOW(), INTERVAL 40 DAY))
) 
ORDER BY priority DESC, prayers.date DESC

union all

SELECT prayers.*
FROM prayers 
LEFT JOIN prayed_for USING (postid) 
WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
and prayers.type = 'prayer' 
and prayers.privacy != 'hidden'
and priority = 'normal' 
and date > DATE_SUB(NOW(), INTERVAL 60 DAY)
ORDER BY prayers.date DESC

union all

SELECT prayers.*
FROM prayers 
LEFT JOIN prayed_for USING (postid) 
WHERE prayed_for.username = '" . $_SESSION['user']['username'] . "' 
and prayers.type = 'prayer' 
and prayers.privacy != 'hidden'
and priority = 'long_term' 
ORDER BY prayers.date DESC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM