how select row in MySQL by check when column data include delimiter - mysql

I have question . If i have user table and a column name be freinds .
I want use some user id inside a column friends with this value : 1|2|45|18 .
This means for example user id =5 have 4 freinds with these id 1|2|45|18.
I don't want use two table for this situation.
How can select each users data when friends with user id = 5 ?
In php we have explode function for slice each delimeter .
Can i set delimeter for this target or i should use two table user and friends in MySQL ?

It's an awful case, especially if you inherit some DB with such a scheme, but to find friends you can use:
SELECT friend.*
FROM user u
left join user friend on concat('|', o.friends, '|') like concat('%|', friend.id, '|%')
where u.id = 5;

Related

SQL Joining the correct username

Say I have the following tables
User
__________
id
username
email
FriendGame
__________
id
useroneid
usertwoid
status
I want to get games that the current user is part of, so I do this:
SELECT *
FROM FriendGame
WHERE useroneid=1663702020516206
OR usertwoid=1663702020516206
AND STATUS =1;
This is fine. Now I want to join the username, but only for the user that ISNT the supplied user (1663702020516206) since in FriendGame the given user exists EITHER as useroneid or usertwoid.
You can pretty much translate your logic directly into an on clause:
SELECT fg.*
FROM FriendGame fg JOIN
User u
ON (fg.useroneid = 1663702020516206 and fg.usertwoid = u.id) or
(fg.usertwoid = 1663702020516206 and fg.useroneid = u.id)
WHERE 1663702020516206 in (fg.useroneid, fg.usertwoid) AND
STATUS = 1;
Actually, the where clause is not necessary to get the right result set, but I think it makes the intention of the query clearer.

Mysql Select one record from another

Hello I have huge problem. In mysql I have 3 tables. Clients , Groups and GroupCross . So I have :
SELECT * FROM clients AS cl
INNER JOIN groupscross AS cr ON cl.cid=cr.cid;
(So now I have matched id in clients with id in groupcross . In groupcross I have also table :cgid .
Now I have data from cr.cgid like : 50,50,60,55,60 so when I command :)
WHERE cr.cgid='function to get id' .
I get all cgid:(50,50,60,55,60)
And here is my question:
How can I do to have all id without 60 ?
I add when I write: WHERE cr.cgid <>60 it shows me all record from database when I want only 50,50,55
Use an IN statement -
SELECT *
FROM `clients` AS `cl`
INNER JOIN `groupscross` AS `cr`
ON `cl`.`cid` = `cr`.`cid`
WHERE `cr`.`cgid` IN(50,55)

create a view and concatenate more than one field to single field name

i want to create a view from two table, members table and assets table,
and concatinate name from members table as one field INCHARGE
here is my code
$host="localhost";
$db="ccm_db";
$pass="";
$user="root";
$conn=mysql_connect($host,$user,$pass) or
die("cannot connect to the database".mysql_error());
mysql_select_db($db,$conn)or
die("cannot select the database".mysql_error());
mysql_query("select a.asset_name as ASSET_NAME,
m.(a.fname,' ',a.mname,' ',a.lname) as INCHARGE from asset a,members m");
i want this so as to have a fullname when i export to exel.
any help????
You have to do a join in order to get a combined result from two tables, like in
select a.asset_name as ASSET_NAME
CONCAT(a.fname, ' ', a.mname, ' ', a.lname) as INCHARGE
from asset a, members m
where a.member = m.id
Or similar. See http://en.wikipedia.org/wiki/Join_(SQL)

Sql Result IN a Query

dont blame for the database design.I am not its database architect. I am the one who has to use it in current situation
I hope this will be understandable.
I have 3 tables containing following data with no foreign key relationship b/w them:
groups
groupId groupName
1 Admin
2 Editor
3 Subscriber
preveleges
groupId roles
1 1,2
2 2,3
3 1
roles
roleId roleTitle
1 add
2 edit
Query:
SELECT roles
from groups
LEFT JOIN preveleges ON (groups.groupId=preveleges.groupId)
returns specific result i.e roles.
Problem: I wanted to show roleTitle instead of roles in the above query.
I am confused how to relate table roles with this query and returns required result
I know it is feasible with coding but i want in SQL.Any suggestion will be appreciated.
SELECT g.groupName,
GROUP_CONCAT(r.roleTitle
ORDER BY FIND_IN_SET(r.roleId, p.roles))
AS RoleTitles
FROM groups AS g
LEFT JOIN preveleges AS p
ON g.groupId = p.groupId
LEFT JOIN roles AS r
ON FIND_IN_SET(r.roleId, p.roles)
GROUP BY g.groupName ;
Tested at: SQL-FIDDLE
I would change the data structure it self. Since It's not normalised, there are multiple elements in a single column.
But it is possible with SQL, if for some (valid) reason you can't change the DB.
A simple "static" solution:
SELECT REPLACE(REPLACE(roles, '1', 'add'), '2', 'edit') from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
A more complex but still ugly solution:
CREATE FUNCTION ReplaceRoleIDWithName (#StringIds VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #RoleNames VARCHAR(50)
SET #RoleNames = #StringIds
SELECT #RoleNames = REPLACE(#RoleNames, CAST(RoleId AS VARCHAR(50)), roleTitle)
FROM roles
RETURN #RoleNames
END
And then use the function in the query
SELECT ReplaceRoleIDWithName(roles) from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
It is possible without function, but this is more readable. Made without editor so it's not tested in anyway.
You also tagged the question with PostgreSQL and it's actually quite easy with Postgres to work around this broken design:
SELECT grp.groupname, r.roletitle
FROM groups grp
join (
select groupid, cast(regexp_split_to_table(roles, ',') as integer) as role_id
from privileges
) as privs on privs.groupid = grp.groupid
join roles r on r.roleid = privs.role_id;
SQLFiddle: http://sqlfiddle.com/#!12/5e87b/1
(Note that I changed the incorrectly spelled name preveleges to the correct spelling privileges)
But you should really, really re-design your data model!
Fixing your design also enables you to define foreign key constraints and validate the input. In your current model, the application would probably break (just as my query would), if someone inserted the value 'one,two,three' into the roles table.
Edit
To complete the picture, using Postgres's array handling the above could be slightly simplified using a similar approach as MySQL's find_in_set()
select grp.groupname, r.roletitle
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
In both cases if all role titles should be shown as a comma separated list, the string_agg() function could be used (which is equivalent to MySQL's group_concat()
select grp.groupname, string_agg(r.roletitle, ',')
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
group by grp.groupname

Select name of creator and editor from user table

How I can select name of creator and editor from users table, creator and editor are different ids in same table, but user table is different table
Is it what you mean?
$sql = "
SELECT id,name
FROM users
WHERE users.id = editors_table.$editor_id
OR users.id = creators_table.$creator_id";
from what i understand, are you saying you have 3 tables - 1 with creator data, 1 with editor data, and a third that references a record in each of the tables using an id?
if so, you'll have to use JOINs to achieve what you want - something like:
SELECT id, name, editors_table.editor_id, creators_table.creator_id
FROM users
LEFT JOIN editors_table ON user.editor_id = editor_table.editor_id
LEFT JOIN creators_table ON user.creator_id = creator_table.creator_id
WHERE editor_table.editor_id = $editor_id_var
OR creator_table.creator_id = $creator_id_var
(you'll want to go through the query as I'm guessing here)