I have problem with the query..
SELECT av.A,
ad.*
FROM ads ad
RIGHT JOIN `B` av
ON ad.serial = av.adid
WHERE ad.status='1'
AND EXISTS (SELECT *
FROM attvalues
WHERE adid =ad.serial
AND (av.atrid = '104'
AND av.atrid = '98'))
i want to retrieve which is matches both conditions 104 AND 98. I can use OR but it will match only 1 condition
You can also give me alternative query if this way is not correct..
I am assuming you want to retrieve records for which BOTH a record with atrid 104 and a record with atrid 98 exist. In that case you want all your records which have 98 OR 104, and there have to be exactly 2, so I suggest a group by and a count(*). Note that I am assuming also that your atrid is in attvalues, as I cannot think of any way to otherwise make your WHERE statement work, you cannot select fro attvalues where some value in B has any value...
SELECT av.A,
ad.*
FROM ads ad
RIGHT JOIN `B` av
ON ad.serial = av.adid
WHERE ad.status='1'
AND EXISTS (SELECT X.adid
FROM attvalues X
WHERE X.adid =ad.serial
AND (X.atrid = '104' OR X.atrid = '98')
GROUP BY X.adid
HAVING COUNT(*) = 2)
Related
I have query like this:
SELECT cs_event.*, cs_file.name, cs_file.extension, cs_user.first_name, cs_user.last_name
FROM cs_event
LEFT JOIN cs_file ON cs_event.idfile = cs_file.idfile
LEFT JOIN cs_user ON cs_event.iduser = cs_user.iduser
WHERE type != 51
AND idportal = 1
UNION DISTINCT
SELECT cs_event.*, cs_file.name, cs_file.extension, cs_user.first_name, cs_user.last_name
FROM cs_event
LEFT JOIN cs_file ON cs_event.idfile = cs_file.idfile
LEFT JOIN cs_user ON cs_event.iduser = cs_user.iduser
WHERE shared_with_users LIKE '%i:2;%'
AND idportal = 1
ORDER BY add_date DESC
LIMIT 6
The problem is following:
Regular user can't see certain types of events (for now it is type 51) and he can see only things which are shared with him.
shared_with_users column can be null or have value - this column have value only for one type of event (type = 50) and for other events it is null.
I need to perform following:
User can access all events except event with type 51 and if the the event is type of 50, I need to check if the event is shared with him (shared_with_users column), and collect that also. Is it possible to make this kind of query?
Try this
SELECT cs_event.*, cs_file.name, cs_file.extension, cs_user.first_name, cs_user.last_name
FROM cs_event
LEFT JOIN cs_file ON cs_event.idfile = cs_file.idfile
LEFT JOIN cs_user ON cs_event.iduser = cs_user.iduser
WHERE type != 51 o or (type = 50 and shared_with_users LIKE '%i:2;%')
AND idportal = 1
ORDER BY add_date DESC
LIMIT 6
I think you can do this as a single query, with logic in the WHERE clause:
SELECT e.*, f.name, f.extension, u.first_name, u.last_name
FROM cs_event e LEFT JOIN
cs_file f
ON e.idfile = f.idfile LEFT JOIN
cs_user u
ON e.iduser = u.iduser
WHERE idportal = 1 AND
(type <> 51 OR shared_with_users LIKE '%i:2;%');
Some notes:
I don't think the LEFT JOINs are necessary. The WHERE clause may be turning them into inner joins anyway, but it is hard to tell without qualified column names.
I added table aliases so the query is easier to write and to read.
The logic for shared_with_users suggests that you have stored a list of values in a string. That is a bad choice.
I have two table,
first is
master_location:
this table is consist of column (id, location)
row 1, id = 1 , location = X
row 2, id = 2 , location = Y
row 3, id = 3 , location = Z
second is
user_access
column (email, id)
row 1 => me#localhost.host , 1
i want to show all other location from master location where email "me#localhost" is NOT present.
I've set up sql:
SELECT ml.idms_location, ml.location
FROM ms_location ml JOIN user_access tu
WHERE ml.id= tu.id
AND !(tu.email = 'me#localhost.host');
but it only show from table user_access where the email is NOT me#localhost.host
is there any sql syntax like SELECT ALL EXCEPT?
thanks
UPDATE
Table 1: master_location
Tabel 2: tm_access
i've write the syntax result as suggested:
SELECT DISTINCT ml.idms_location,ml.location
FROM ms_location ml
LEFT OUTER JOIN tm_userlocation tu
ON ml.idms_location = tu.idms_location
WHERE COALESCE(tu.email,'john#mscid.com') = 'john#mscid.com';
the result
USING THIS SQL SYNTAX:
SELECT ms.idms_location, ms.location
FROM ms_location AS ms LEFT JOIN tm_userlocation AS tu
ON ms.idms_location = tu.idms_location
WHERE tu.email !='john#mscid.com' OR tu.email IS NULL;
the result where i execute is only the first ID is missing, the no. 3 and no. 5 should removed too
screenshot:
Following statement will return all rows from ms_location that have no corresponding row in user_access.
SELECT ml.idms_location,ml.location
FROM master_location ml
WHERE NOT EXISTS (
SELECT *
FROM user_access tu
WHERE tu.idms_location = ml.idms_location
AND tu.email = 'john#mscid.com'
)
SQL Fiddle Demo
You've left a bit to be guessed at (I'm assuming your cardinality is 1..*), but I think what you're asking for is a result set showing the ms_location records that don't have an associated user_access record with the email address 'me#localhost.host'. That is, from your given sample data, only location X has an associated user_access record with that email address (it's also the only record). Locations Y and Z do not have associated user_access records with the specified address. These are the ones you want.
If I've interpreted you correctly, try this:
SELECT ml.idms_location, ml.location
FROM ms_location ml
WHERE ml.id NOT IN (
SELECT id FROM user_access WHERE email = 'me#localhost.host')
If I haven't, don't.
As per your data Your Query should be
select m.`id`, m.`location` from `master_location` as m
WHERE
m.`id` NOT IN ( select `id` from `user_access` WHERE `email` = 'john#mscid.com' ) ;
Check the SQL Fiddle Link
http://sqlfiddle.com/#!2/28b50/3
This MySQL statement give me all id_duel_player for player with id_player=30 and it work fine.
SELECT b.id_duel_player
FROM duels a
INNER JOIN duel_player b
ON a.id_duel = b.id_duel
WHERE id_player = 30
UNION ALL
SELECT c.id_duel_player
FROM duel_player c
INNER JOIN
(
SELECT aa.*
FROM duels aa
INNER JOIN duel_player bb
ON aa.id_duel = bb.id_duel
WHERE bb.id_player = 30
) d ON c.id_duel = d.id_duel AND c.id_player <> 30
I want to make MySQL statement for UPDATE (fields from duel_player table) all of this id_duel_player that returns this select statement.
UPDATE duel_player
SET num = 2,
total = 5
WHERE (duel_player.id_duel_player = id_duel_player's from above SELECT statement)
I want most effective and fastest way to do this.
Thanks
For 200-400 rows it's likely fastest to create a temporary table with the results, and then do the UPDATE with a join:
CREATE TEMPORARY TABLE id_duel_players AS
SELECT b.id_duel_player as id FROM duels a ...
UPDATE duel_player
JOIN id_duel_players ON duel_player.id_duel_player = id_duel_players.id
SET num = 2,
total = 5
For smaller result sets you may find the IN operator sufficiently fast (... WHERE id_duel_player IN (SELECT ...)), but I've found it unreliable for result sets with hundreds of rows. (Unreliable = suddenly no matches are found, no idea why, I haven't investigated.)
i am trying to write the Query for three things .My table structure is like that
You can see Schema at http://sqlfiddle.com/#!2/56c2d/1
I am trying to write the query in MYSQL
user:- table
user_id
user_fname
This is User tabke which will save User Information
group:- "group" and "subgroup" is maintain in same table using column "group_parent_group_id"
group_id
group_title
group_parent_group_id(INT)
This is group table which will save Group and Subgroups
user_group: table
user_group_id
user_group_user_id
user_group_group_id
This ill store both User and Group relation using their Id
I am trying to write the Query for three things. Fetching Users Groups, Subgroups
1) Query to fetch list of All Groups for User Register. Query is gelow and is giving error
Query:
select user.id, user.user_fname, group.group_id, group.group_title
from `user`
inner join user_group on user_group.user_group_user_id = user.user_id
inner join group on group.group_id = user_group.user_group_group_id
where user_group.user_group_user_id = 1 and user_group.group_parent_group_id = 0
2) I am Looking the query to fetch all subgroups(For Whom user is already Register) for Group Id 1,2 or 1
3) I am Looking the query to fetch all subgroups(For Whom user is Not Register yet) for Group Id 1,2 or 1. Ideal is for giving him randomly suggest a subgroup to add
Please Help. I am a newbie in DB :(
Your query is probably failing as you have a table called group, which is a reserved word. You can use back tics to delimit the name to get away with this (as follows) but it would be a better idea to change the table name.
SELECT user.id, user.user_fname, `group`.group_id, `group`.group_title
FROM `user`
INNER JOIN user_group ON user_group.user_group_user_id = user.user_id
INNER JOIN `group` ON `group`.group_id = user_group.user_group_group_id
WHERE user_group.user_group_user_id = 1
AND user_group.group_parent_group_id = 0
EDIT updated for queries I think the OP requires.
First query will get a list of all the groups (ones that have no parent group id) that a user (in this case id 28) is a member of
SELECT y2m_user.user_id, y2m_user.user_first_name, y2m_group.group_id, y2m_group.group_title
FROM y2m_user
INNER JOIN y2m_user_group ON y2m_user_group.user_group_user_id = y2m_user.user_id
INNER JOIN y2m_group ON y2m_group.group_id = y2m_user_group.user_group_group_id
WHERE y2m_user.user_id = 28
AND y2m_group.group_parent_group_id = 0
This query will get a list of all the sub groups (ones where the parent group id is greater than 0) that a user (in this case id 28) is a member of
SELECT y2m_user.user_id, y2m_user.user_first_name, y2m_group.group_id, y2m_group.group_title
FROM y2m_user
INNER JOIN y2m_user_group ON y2m_user_group.user_group_user_id = y2m_user.user_id
INNER JOIN y2m_group ON y2m_group.group_id = y2m_user_group.user_group_group_id
WHERE y2m_user.user_id = 28
AND y2m_group.group_parent_group_id > 0
This query will get a list of all the sub groups (ones where the parent group id is greater than 0) that a user (in this case id 28) is NOT a member of
SELECT y2m_user.user_id, y2m_user.user_first_name, y2m_group.group_id, y2m_group.group_title
FROM y2m_user
CROSS JOIN y2m_group
LEFT OUTER JOIN y2m_user_group ON y2m_user_group.user_group_user_id = y2m_user.user_id AND y2m_group.group_id = y2m_user_group.user_group_group_id
WHERE y2m_user.user_id = 28
AND y2m_group.group_parent_group_id > 0
AND y2m_user_group.user_group_id IS NULL
Please excuse any typos as not tested (with your test data there are no sub groups).
I have this data in a table, for instance,
id name parent parent_id
1 add self 100
2 manage null 100
3 add 10 200
4 manage null 200
5 add 20 300
6 manage null 300
How can I left join or inner join this table itself so I get this result below?
id name parent
2 manage self
4 manage 10
6 manage 20
As you can I that I just want to query the row with the keyword of 'manage' but I want the column parent's data in add's row as the as in manage's row in the result.
Is it possible?
EDIT:
the simplified version of my actual table - system,
system_id parent_id type function_name name main_parent make_accessible sort
31 30 left main Main NULL 0 1
32 31 left page_main_add Add self 0 1
33 31 left page_main_manage Manage NULL 0 2
my actual query and it is quite messy already...
SELECT
a.system_id,
a.main_parent,
b.name,
b.make_accessible,
b.sort
FROM system AS a
INNER JOIN -- self --
(
SELECT system_id, name, make_accessible, sort
FROM system AS s2
LEFT JOIN -- search --
(
SELECT system_id AS parent_id
FROM system AS s1
WHERE s1.function_name = 'page'
) AS s1
ON s1.parent_id = s2.parent_id
WHERE s2.parent_id = s1.parent_id
AND s2.system_id != s1.parent_id
ORDER BY s2.sort ASC
) b
ON b.system_id = a.parent_id
WHERE a.function_name LIKE '%manage%'
ORDER BY b.sort ASC
result I get currently,
system_id main_parent name make_accessible sort
33 NULL Main 0 1
but I am after this,
system_id main_parent name make_accessible sort
33 self Main 0 1
You just need to reference the table twice:
select t1.id, t1.name, t2.id, t2.name
from TableA t1
inner join TableA t2
on t1.parent_id = t2.Id
Replace inner with left join if you want to see roots in the list.
UPDATE:
I misread your question. It seems to me that you always have two rows, manage one and add one. To get to "Add" from manage:
select system.*, (select parent
from system s2
where s2.parent_id = system.parent_id
and s2.name = 'add')
AS parent
from system
where name = 'manage'
Or, you might split the table into two derived tables and join them by parent_id:
select *
from system
inner join
(
select * from system where name = 'add'
) s2
on system.parent_id = s2.parent_id
where system.name = 'manage'
This will allow you to use all the columns from s2.
Your data does not abide to a child-parent hierarchical structure. For example, your column parent holds the value 10, which is not the value of any id, so a child-parent association is not possible.
In other words, there's nothing that relates the record 2,manage,null to the record 1,add,self, or the record 4,manage,null to 3,add,10, as you intend to do in your query.
To represent hierarchical data, you usually need a table that has a foreign key referencing it's own primary key. So your column parent must reference the column id, then you can express a child-parent relationship between manage and add. Currently, that's not possible.
UPDATED: Joining by parent_id, try:
select m.id, m.name, a.parent
from myTable m
join myTable a on m.parent_id = a.parent_id and a.name = 'add'
where m.name = 'manage'
Change the inner join to a left join if there may not be a corresponding add row.