I want to display a set of data in a single row, but I don't seem to implement it, I tried several ways, it still doesn't work. I want to display all permission names assigned for a role name in a single row.
for example :
| editor | edit-user, delete-user, delete-role |
| deleter | delete-user |
here's my sql
$datas = DB::SELECT(' SELECT roles.id, roles.name as roleName, permissions.name as PermName
FROM roles
LEFT JOIN role_has_permissions
ON (roles.id = role_has_permissions.role_id)
LEFT JOIN permissions
ON (role_has_permissions.permission_id = permissions.id)
ORDER BY roles.id');
thank you in advance :)
Can you join the two middle joins in a subquery:
LEFT JOIN (
SELECT
permissions.name as PermName
,role_has_permissions.role_id
FROM role_has_permissions
LEFT JOIN permissions ON role_has_permissions.permission_id = permissions.id)
ON roles.id = role_has_permissions.role_id
Related
I have two tables like these:
Table "users":
user_id | source
----------------
1 | 2
2 | 2
3 | 3
4 | 0
Table "sources":
source_id | name
----------------
1 | "one"
2 | "two"
3 | "three"
4 | "four"
Now I need to SELECT (*) FROM source and additionally COUNT "users" that have this source, BUT if there is an additional filter(requests by PHP mysqli), then additionally sort "sources" table by its users count.
What is the best way to do so, and is it possible to do in one statement?
--------------Added editing----------
The first part(SELECT with count from another table) I'm doing this way:
SELECT
id, name
(select count(*) from users where source = sources.id) as sourceUsersCount
FROM sources
And now, how to order this list by users count in each source?
Please check the below query if this is what you need.
select s.*,a.c from sources s
left join
(select count(*) as c,source as src
from user u join sources s
on s.source_id = u.source group by u.source) a
on s.source_id = a.src;
Count the number of users:
SELECT sources.*, COUNT(users.user_id) FROM sources
LEFT JOIN users ON users.source_id = sources.source_id
GROUP BY sources.source_id;
I assume by filters you mean the WHERE clause:
SELECT sources.*, COUNT(users.user_id) FROM sources
LEFT JOIN users ON users.source_id = sources.source_id
WHERE sources.source_id = 2
GROUP BY sources.source_id;
And you can always attach an ORDER BY on the end for sorting:
SELECT sources.*, COUNT(users.user_id) FROM sources
LEFT JOIN users ON users.source_id = sources.source_id
GROUP BY sources.source_id
ORDER BY sources.source_id DESC;
Achieved it by doing so:
SELECT
sources.*,
count(users.source) as sourceUsersCount
FROM sources
LEFT JOIN users ON sources.id = users.source
//In case of additional filters
WHERE
id != 0 AND (name LIKE %?% OR id LIKE %?%)
//\\
GROUP BY sources.id
//In case of sorting by "users" count
ORDER BY sourceUsersCount ASC
//\\
Is it the best way, or maybe there are some faster variants?
i am having an bit of trouble understanding JOINS with mysql.
i have 3 tables.
gold_sended) user_id | sended
register) user_id | gold_swap_id
google_users) oauth_uid | portal_name
now what needs to be done is as follow.
first i need all the portal_names of google_users where oauth_id = the same as register.user_id
Next thing is i also need to check if the register.user_id = gold_sended.user_id
If the user_id from register is the same als gold_sended user_id then display
the portal name. If not then display nothing.
I never have worked with joins so i am an bit lost on how to do it propperly.
Ok its now solved.
SELECT
google_users.portal_name,
gold_sended.user_id,
gold_sended.date,
COUNT(gold_sended) as total_runs
FROM
register_gold_swap
LEFT JOIN google_users on register_gold_swap.user_id=google_users.oauth_uid
LEFT JOIN gold_sended on register_gold_swap.user_id=gold_sended.user_id
WHERE
register_gold_swap.gold_swap_id = "1"
AND register_gold_swap.status = "1"
GROUP BY google_users.portal_name
Is now outputting the correct data. Thank you all
select
g.portal_name
from
gold_sended as gs
left join register as r
on g.oauth_id=r.user_id
left join google_users as g
on gs.user_id=g.oauth_id
try this
I'm really unsure how best to go about writing this query. I have 3 tables and I need to run a query pulling data from one, based on conditions in the others.
Tables: surveys, survey_countries, survey_categories
surveys:
id | survey_id | network_id
survey_countries:
id | survey_id | network_id | country
survey_categories:
id | survey_id | network_id | category
(The survey_id in survey_countries and survey_categories relates to the survey_id column in the surveys table as opposed to the id column).
I need to retrieve data from surveys for a specific country and a specific category. Then I need to be able to UNION for other categories, but I guess I can do that later. My attempt:
SELECT surveys.*
FROM survey_countries
LEFT JOIN surveys ON survey_countries.survey_id = surveys.survey_id ANd survey_countries.network_id = surveys.network_id
LEFT JOIN survey_categories ON survey_countries.survey_id = surveys.survey_id AND survey_categories.network_id = surveys.network_id
WHERE survey_countries.country = 'GB'
AND survey_categories.category = 'my_category'
GROUP BY surveys.id
Thanks!
EDIT: the following seems to work:
SELECT s.*, ca.category, co.country
FROM surveys s
LEFT JOIN survey_countries co ON s.survey_id = co.survey_id AND s.network_id = co.network_id
LEFT JOIN survey_categories ca ON s.survey_id = ca.survey_id AND s.network_id = ca.network_id
WHERE ca.category = 'uncategorised'
AND co.country = 'GB';
I'm just not sure it's the best way to do it since I need to grab surveys with multiple categories later on?
Without example data and an example output, helping you on this query is very difficult. However..... your 2nd join relates survey_countries with surveys. I think you mean to join it to the survey_categories. Also, you have a Group By, with no aggregate functions. Get rid of it until you have too much information an need to summarize columns
I am not saying this is correct, but it is slightly more 'correct' than yours
SELECT surveys.*
FROM survey_countries
LEFT JOIN surveys
ON survey_countries.survey_id = surveys.survey_id
AND survey_countries.network_id = surveys.network_id
LEFT JOIN survey_categories
ON survey_categories.survey_id = surveys.survey_id
AND survey_categories.network_id = surveys.network_id
WHERE survey_countries.country = 'GB'
AND survey_categories.category = 'my_category'
(If you can, load up a schema and sample data in sqlfiddle. It will make this problem easier to solve.)
I have a row with some values hyphen-delimited:
table: live_customers
row: areas
id | areas
1 | 10-20-30
2 | 40-50-60
...
Using this...
LEFT JOIN $table5 AS table5 ON live.areas REGEXP CONCAT('(^|-) ?',table5.id,' ?($|-)')
My results looks like:
(tab id:1) area: 10
(tab id:1) area: 20
...
(tab id:2) area: 40
...
But i expect:
(tab id:1) area: 10,20,30
(tab id:2) area: 40,50,60
How could i solve that?
EDIT:
The full query looks like:
SELECT live.*,
live.id AS lid,
table1.id, table1.value AS tn_val,
table2.id, table2.value AS tp_val,
table3.id, table3.value AS ht_val,
table5.id, table5.value AS ar_val
FROM $dblist AS live
LEFT JOIN $table1 AS table1 ON live.town = table1.id
LEFT JOIN $table2 AS table2 ON live.htype = table2.id
LEFT JOIN $table3 AS table3 ON live.ht = table3.id
LEFT JOIN $table5 AS table5 ON live.areas REGEXP CONCAT('(^|-) ?',table5.id,' ?($|-)')
ORDER BY live.id ASC
PHP echoes:
...
if ($post['areas']){ // Debugging areas stuff
echo '<strong>'.$_areas.': (ar_val)</strong> '.$post['ar_val'].'<p>';
echo '<strong>'.$_areas.': (areas)</strong> '.$post['areas'].'<p>';
}
...
EDIT2:
It's quite hard for me to explain my issue in English, but i'm trying the best i can :)
in the table "live_customers" i does have this:
id | areas
1 | 10-20-30
2 | 40-50-60
...
in the table "areas" (that is a completely different table):
id | value
38 | Zone1
39 | Zone2
40 | Zone3
...
In the SQL query you see just tables variables because i previousvly declared them at the top of page:
$table5 = 'areas';
$dblist = 'live_customers';
etc..
Solution
Thanks anyone for their answers and for let me know "GROUP_CONCAT".
Here is my solution:
SELECT live.*,
live.id AS lid,
table1.id, table1.value AS tn_val,
table2.id, table2.value AS tp_val,
table3.id, table3.value AS ht_val,
table5.id, GROUP_CONCAT(table5.value) AS ar_val
FROM $dblist AS live
LEFT JOIN $table1 AS table1 ON live.town = table1.id
LEFT JOIN $table2 AS table2 ON live.htype = table2.id
LEFT JOIN $table3 AS table3 ON live.ht = table3.id
LEFT JOIN $table5 AS table5 ON FIND_IN_SET(table5.id, REPLACE(live.areas, '-', ','))
GROUP BY live.id
Result is what i expected ^^
Take it together with GROUP_CONCAT()
First thing to say is that your schema violates First Normal Form (1NF) in that the column areas is not atomic. You should not be putting 3 different values in one column.
Next you say you have a table called live_customers with a row called areas. This is nonsense. Rows do not have names, columns do. You show a bit of table with 2 columns id and areas. What table is this?
Next in the query there is no mention of a table called live_customers.
Next, if there is a column called areas in the table with the alias of live, then the output should contain that column since you are selecting live.*. That being the case, your results cannot be what you showed us, since it would contain a results column with data like 10-20-30
Finally those cannot be the results of the posted query since I can see a results column of lid specified.
If you would care to take some time over ensuring that the questionyou post makes sense, then you might get a reasonable answer.
EDIT by:lawrence.
I got the right query now
select *
from users, friends
where (users.id=friends.user_id1 and friends.user_id2=$profileID) or (users.id=friends.user_id2 and friends.user_id1=$profileID)
Question answered
I need some help joining results from my friends and users table
This is what my friends table look like
id user_id1 user_id2
1 | 2 | 3
1 | 2 | 4
1 | 2 | 5
1 | 6 | 2
Users table
id name
2 | sarah
3 | emma
4 | lawrence
5 | cynthia
6 | suzie
I could easily just have two rows for each relation and do a simple query.
But i prefer having one row per relation,
So lets assume that we are watching page member.php?profile=2
and there is a list of friends, what does the query look like.
This works fine if i have two rows per relation but i dont want that....
SELECT * FROM friends, users WHERE friends.user_id1 = $profileID AND friends.user_id2 = users.id ORDER BY friends.id DESC LIMIT 16
Do you get me? something along like
SELECT * FROM friends,users WHERE friends.user_id1 = $profileID AND ALSO WHERE friends.user_id2 = $profileID AND THEN GET FROM users WHERE users.id = friends.user_id1 AND ALSO WHERE users.id = friends.user_id2
I hope I made myself clear
I'm not sure i understand your question but won't this do?
SELECT * FROM friends, users where friends.user_id1 = $profileID or friends.userid2 = $profileID and users.id = friends.user_id1 or users.id = friends.user_id2
You want a left join (using the LEFT JOIN operator), not a cartesian join (using the FROM table1, table2 syntax).
http://www.w3schools.com/sql/sql_join_left.asp
Tip: With your cross-reference table instead of having an id column you can create a compound key.