Print out a union select - php

I have the following query:
$query = mysql_query(" ( SELECT naam
FROM users_social
WHERE user_id = 1 )
UNION
( SELECT COUNT(DISTINCT DATE(datetime)) as days
FROM users_social_invoer
WHERE user_id = 1 )"
);
Now I can echo the first part of the query (the 'naam') with the following echo:
echo mysql_fetch_row($row_query[0]);
However echo'ing $row_query[1] does NOT print out the 2nd part of the query (the union select) as I would like to. How do I actually print out that part of the query? thanks

You need JOIN instead of UNION
SELECT us.naam, count(DISTINCT DATE(usi.datetime)) as days
FROM users_social as us
JOIN users_social_invoer as usi
ON us.user_id = usi.user_id
WHERE us.user_id = 1
GROUP BY us.naam

Related

MySQL return union select results separated in groups

I would like to know if is possible to return the results from UNION grouped by their alias.
For instance:
(SELECT * FROM table1) AS first
UNION
(SELECT * FROM table2) AS second
so that the result is:
first = contains all table1 rows
second = contains all table2 rows
Practically i want an associative array like this:
[]=>[
'first'=>[table1 results],
'second'=>[table2 results]
]
I tried it but doesn't work. Maybe i'm doing it bad.
Can this be done with a single query or i've to do 2 separated queries.
Thanks.
You cannot do this with union because it removes duplicates. You can with union all.
One way is:
SELECT t.*, 0 as which FROM table1 t
UNION ALL
SELECT t.*, 1 FROM table2 t
ORDER BY which;
If you don't want to see which in the output, use a subquery:
select . . .
from (select t.*, 0 as which from table1 t union all
select t.*, 1 as which from table1 t
) t
order by which;

How to group by a column with forloop and union all

Hi this is my query from this query i am getting 3 records i want only one record and i am trying to group by studentid
foreach ($gdFinaldata['gdskill'] as $skillId => $skillScore){
$filterQuery .= $union_all. "SELECT stu.student_pid
FROM tbl_students stu LEFT JOIN r_job_invitations jbi ON stu.student_email = jbi.email
LEFT JOIN r_job_scores jsc ON jsc.student_id = stu.student_pid
WHERE job_id = ".$jobID." AND skill_id = ".$skillId." AND gd_score >= ".$skillScore." ";
$union_all=" UNION ALL ";
} //for ends here
the recodrs will come like this:
SELECT stu.student_pid FROM tbl_students stu LEFT JOIN r_job_invitations jbi ON stu.student_email = jbi.email LEFT JOIN r_job_scores jsc ON jsc.student_id = stu.student_pid WHERE job_id = 88 AND skill_id = 3 AND gd_score >= 1
UNION ALL
SELECT stu.student_pid FROM tbl_students stu LEFT JOIN r_job_invitations jbi ON stu.student_email = jbi.email LEFT JOIN r_job_scores jsc ON jsc.student_id = stu.student_pid WHERE job_id = 88 AND skill_id = 63 AND gd_score >= 2
UNION ALL
SELECT stu.student_pid FROM tbl_students stu LEFT JOIN r_job_invitations jbi ON stu.student_email = jbi.email LEFT JOIN r_job_scores jsc ON jsc.student_id = stu.student_pid WHERE job_id = 88 AND skill_id = 128 AND gd_score >= 3
After this i want to add group by how can i do that i tried like this:
$groupby = "GROUP BY student_id";
$filterStudents = $conn->query($filterQuery.$groupby);
My issue is still returning 3 records i want to group by student
For Reference:
There are several ways to do this.
Use union instead of union all, this will retain only unique entries
select ...
union
select ...
union
select ...
If you want to keep union all (why do you?), use parenthesis around your selects and append group by after it
select student_pid
( select student_pid, student_id from ...
union all
select student_pid, student_id from ...
union all
select student_pid, student_id from ... ) as t
group by student_id
Your PHP would then look like
foreach (...) {
$filterQuery .= $union_all. "SELECT stu.student_pid, jsc.student_id ..."
// ...
}
$outerQuery = "select student_pid ("
$groupby = ") as t GROUP BY student_id";
$filterStudents = $conn->query($outerQuery . $filterQuery . $groupby);
Instead of group by, you can also use distinct, e.g.
select distinct student_pid
( select student_pid from ...
union all
select student_pid from ...
union all
select student_pid from ... ) as t
Collect the result in an array and then use array_unique
Although this is the least efficient, since it fetches all entries instead of the relevant parts.

correct query for join two querys

I have this query for select a list
$sql="select * from buy_log where (client_id not in
(select selected_client_id from action_log where media_id=buy_log.media_id and client_id=$client_id )
and totalVisit>0 and coin_id=3 or coin_id=4 or coin_id=5)";
and this is my second select
while($row=mysqli_fetch_assoc($result)){
$media_id = $row['media_id'];
$sql2 = "select * from comment_media,comment_list where comment_list.id=comment_media.id and media_id='$media_id' order by rand() limit 2";
}
i try to use join for one query and this is my try :
SELECT S.*,WW.Comments,WW.Comments_id
FROM buy_log S
INNER JOIN
(
SELECT M.media_id,GROUP_CONCAT(W.Comment SEPARATOR '!###!') as Comments,GROUP_CONCAT(W.id SEPARATOR ',') as Comments_id
FROM comment_list W,comment_media as M
Where W.id=M.id and M.media_id='$media_id' and W.used = 0
) WW
ON S.media_id = WW.media_id
where (client_id not in
(select selected_client_id from action_log where media_id=S.media_id and client_id='1234' )
and totalVisit>0 and coin_id=3 or coin_id=4 or coin_id=5)
but here is my problem
Where W.id=M.id and M.media_id='$media_id' and W.used = 0
I don't know how can i set $media_id
any solution ?
UPDATE
Tables Info :
Tables Info : Pic
This should work:
You're extracting media id from that original query, looping through results and using the media id to assign the value $media_id in the php loop, where you perform another query.
The join seems syntactically right just need to reference the buy_log table inside the subquery.
SELECT S.*,WW.Comments,WW.Comments_id
FROM buy_log S
INNER JOIN
(
SELECT M.media_id,GROUP_CONCAT(W.Comment SEPARATOR '!###!') as Comments,GROUP_CONCAT(W.id SEPARATOR ',') as Comments_id
FROM comment_list W,comment_media as M
Where W.id=M.id and M.media_id= S.media_id and W.used = 0
) WW
ON S.media_id = WW.media_id
where (client_id not in
(select selected_client_id from action_log where media_id=S.media_id and client_id='1234' )
and totalVisit>0 and coin_id=3 or coin_id=4 or coin_id=5)
I guess that first query can be rewritten as follows... does it help?
SELECT b.media_id
FROM buy_log b
LEFT
JOIN action_log a
ON a.selected_client_id = b.client_id
AND a.media_id = b.media_id
AND a.client_id = $client_id
WHERE b.totalVisit > 0
AND b.coin_id IN(3,4,5)
AND a.selected_client_id IS NULL;

I cant figure out how to write an sql query to display the information how I want

I've gotten my database set up for my website and I'm a little baffled on how I should write the SQL query to display the information how I want it.
Here's an image of how my database is setup and an example of how I want to display it:
Here's the SQL query I wrote to get the information (Im open to writing a better solution)
SELECT * FROM drinks_category, drinks_lookup, drinks
WHERE drinks.drink_id = drinks_lookup.drink_id
AND drinks_lookup.drinks_category_id = drinks_category.drinks_category_id
This gets me all the info but I'm not sure how to write the output to get it to show how i want.
One solution is to order by category:
SELECT *
FROM drinks_category, drinks_lookup, drinks
WHERE drinks.drink_id = drinks_lookup.drink_id
AND drinks_lookup.drinks_category_id = drinks_category.drinks_category_id
ORDER BY drinks_category.drink_category_title
With that, you can loop in PHP, and output a new header whenever a new category appears. Something like this:
<?php
$last_category = 0;
foreach($data as $row) {
if($row['drinks_category_id'] != $last_category) {
echo '<h1>' . $row['drink_category_title'] . '</h1>';
}
echo '<div>' . $row['drinks_name'] . '</div>';
$last_category = $row['drinks_category_id'];
}
?>
You should probably use nested html lists instead of the markup above, but this should get you started.
Since you use PHP, the best way to do this is to use an outer-inner-query loop:
Outer query: SELECT * FROM drings_category, then loop:
Display drink_category_title
Use drink_category_id as $ID for SELECT drinks.drink_name FROM drinks INNER JOIN drinks_lookup ON drinks.drink_id=drinks_lookup.drink_id WHERE drinks_lookup.drink_category_id=$ID
Loop and display drinks
Hideously over complicated way to do it in a single sql statement for 3 fixed columns, coping with up to 1000 drinks in each category.
SELECT DrinkCategory1Subselect.drink_name AS 'Drink Category Title', DrinkCategory2Subselect.drink_name AS 'Drink Category Title 2', DrinkCategory3Subselect.drink_name AS 'Drink Category Title 3'
FROM (SELECT a.i+b.i*10+c.1*100 AS aCounter
FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c) Deriv1
INNER JOIN (SELECT c.drink_name,
#Counter := #Counter + 1 AS aCounter
FROM drinks_category a
INNER JOIN drinks_lookup b ON a.drink_category_id = b.drink_category_id
INNER JOIN drinks c ON b.drink_id = c.drink_id
CROSS JOIN (SELECT #Counter:=0) NothingUseful
WHERE a.drink_category_id = 1
ORDER BY c.drink_id) DrinkCategory1Subselect
ON DrinkCategory1Subselect.aCounter = Deriv1.aCounter
INNER JOIN (SELECT c.drink_name,
#Counter := #Counter + 1 AS aCounter
FROM drinks_category a
INNER JOIN drinks_lookup b ON a.drink_category_id = b.drink_category_id
INNER JOIN drinks c ON b.drink_id = c.drink_id
CROSS JOIN (SELECT #Counter:=0) NothingUseful
WHERE a.drink_category_id = 2
ORDER BY c.drink_id) DrinkCategory2Subselect
ON DrinkCategory2Subselect.aCounter = Deriv1.aCounter
INNER JOIN (SELECT c.drink_name,
#Counter := #Counter + 1 AS aCounter
FROM drinks_category a
INNER JOIN drinks_lookup b ON a.drink_category_id = b.drink_category_id
INNER JOIN drinks c ON b.drink_id = c.drink_id
CROSS JOIN (SELECT #Counter:=0) NothingUseful
WHERE a.drink_category_id = 3
ORDER BY c.drink_id) DrinkCategory3Subselect
ON DrinkCategory3Subselect.aCounter = Deriv1.aCounter
WHERE DrinkCategory1Subselect.drink_name IS NOT NULL
OR DrinkCategory2Subselect.drink_name IS NOT NULL
OR DrinkCategory3Subselect.drink_name IS NOT NULL
ORDER BY Deriv1.aCounter
Not tested. Better to do the formatting in php, but was bored

SQL Union only counting one query

Im trying to count rows in a table. Currently im using this:
$sql = "SELECT COUNT(*)
FROM `friends`
WHERE `user1`='".$user1."'
AND `user2`='".$user2."'
AND `valid`=0
UNION
SELECT COUNT(*)
FROM `friends`
WHERE `user1`='".$user2."'
AND `user2`='".$user1."'
AND `valid`=0";
As you see, user1 can be both $user1 AND $user2. but it does not count the rows after the UNION, it only does the first query before UNION so im ending up with 0 when i actually should be counting 1 row.
How do I solve this?
Another alternative, replace your query with this:
$sql = "SELECT COUNT(*)
FROM `friends`
WHERE (
(`user1`='".$user1."' AND `user2`='".$user2."') OR
(`user1`='".$user2."' AND `user2`='".$user1."')
)
AND `valid`=0";
Your query is actually returning 2 records - 0 for the first count and 1 for the second. You could use a sub-query to SUM() your results...
$sql = "SELECT SUM(A) AS COUNT FROM
(SELECT COUNT(*) AS A
FROM `friends`
WHERE `user1`='".$user1."'
AND `user2`='".$user2."'
AND `valid`=0
UNION
SELECT COUNT(*)
FROM `friends`
WHERE `user1`='".$user2."'
AND `user2`='".$user1."'
AND `valid`=0
)";
Use UNION ALL instead. UNION will exclude duplicate rows.
You can use an even simpler solution:
SELECT COUNT(*)
FROM friends
WHERE
$user1 IN (user1,user2) AND
$user2 IN (user1,user2) AND
valid = 0

Categories