Showing List Where ID is not Present - mysql

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

Related

SQL select rows that have one value but not another

I have a table in SQL which will contain multiple rows for one id, as below
accountid Productname
1 GL
1 IP
1 MI
2 GL
2 IP
2 PA
3 MI
3 CP
3 IP
4 GL
4 CP
4 CI
I want to be able to select all accounts which have certain products but not other. For example all that have IP or GL but not MI, using the sample table above this would return accounts 2 and 4.
SELECT ccx_accountidname
FROM (
SELECT ccx_accountidname, ccx_productname
FROM Filteredccx_leadresearch
WHERE ccx_productname IN ('GL','IP')
AND ccx_accountidname IS NOT NULL
) AS T
WHERE ccx_productname NOT IN ('MI')
ORDER BY ccx_accountidname
and
SELECT DISTINCT LR1.ccx_accountidname
FROM Filteredccx_leadresearch LR1
LEFT JOIN Filteredccx_leadresearch LR2 ON LR1.ccx_accountid = LR2.ccx_accountid
AND LR2.ccx_productname IN ('GL', 'IP')
WHERE LR1.ccx_productname NOT IN ('MI')
AND LR1.ccx_accountidname IS NOT NULL
ORDER BY LR1.ccx_accountidname
Both give basically the same results, is there any way this can be done?
Thanks in advance for any help
Could you try this:
SELECT DISTINCT T1.Accountidname FROM TheTableThatContainsAccountnames as T1
JOIN AccountProductsTable as T2 on T1.AccountId=T2.AccountId
WHERE T2.ProductName = 'ProductYouWant'
AND T2.ProductName = 'AnOtherProductYouWant'
According to your post, all you really need is a simple query with the correct and logic. You want all accounts with Product name GL or IP but not in MI. This will do it without any other joins.
SELECT ccx_accountidname
FROM Filteredccx_leadresearch
WHERE
ccx_productname in ('GL','IP')
and ccx_productname not in ('MI')
EDIT
This will get you the account, though I doubt it will work in your overall solution. It's just hard to tell without seeing your complete dataset. This could be done with parameters too.
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
IF OBJECT_ID('tempdb..#TempTableTwo') IS NOT NULL
DROP TABLE #TempTableTwo
create table #TempTable (accountid int, productname char(2))
insert into #TempTable (accountid,productname) values
(1,'GL'),
(1,'IP'),
(1,'MI'),
(2,'GL'),
(2,'IP'),
(2,'MA')
select distinct
t1.accountid,
1 as T
into #TempTableTwo
from
#TempTable t1
where
productname in ('GL','IP')
union all
select distinct
t1.accountid,
-1 as T
from
#TempTable t1
where
productname in ('MI')
select
accountid
from #TempTableTwo
group by accountid
having sum(T) > 0
I might be late for the game, but this should do the trick, if anyone is trying to solve a similar problem. I renamed your table and it's columns:
Filteredccx_leadresearch -> l_search
ccx_accountidname -> a_name
ccx_productname -> p_name
And here's the SQL:
(SELECT DISTINCT t1.a_name
FROM l_search t1
JOIN l_search t2 ON t1.a_name = t2.a_name
WHERE t1.p_name = 'IP'
OR t2.p_name = 'GL')
MINUS
(SELECT DISTINCT t1.a_name
FROM l_search t1
JOIN l_search t2 ON t1.a_name = t2.a_name
WHERE ((t1.p_name = 'IP'OR t1.p_name = 'GL') AND t2.p_name = 'MI')
OR
(t1.p_name = 'MI' AND (t1.p_name = 'IP' OR t1.p_name = 'GL')));
First set:
cross product of table on itself with same IDs, get account IDs which have a product 'IP' or 'GL'.
Second set:
cross product of table on itself with same IDs, get account IDs which have p_name ('IP' OR 'GL') on first cross property AND 'MI' on second.
Also, get those IDs, which have the same but the other way around: p_name 'MI' on first cross property AND ('IP' OR 'GL') on second.
And finally subtract the second from the first.
Here is a simple way to include the accounts that match either IP or GL and exclude those accounts if they have an record for MI without using a subquery.
This is assuming t1 is a table that has unique account numbers in accountid and t2 is the table you have shown above that has accountid and Productname columns.
SELECT DISTINCT
t1.accountid
FROM t1
LEFT JOIN t2 AS t2_match
ON t1.accountid = t2_match.accountid
AND
(
t2_match.Productname = 'IP'
OR t2_match.Productname = 'GL'
)
LEFT JOIN t2 AS t2_not_match
ON t1.accountid = t2_not_match.accountid
AND t2_not_match.Productname = 'MI'
WHERE
t2_match.accountid IS NOT NULL
AND t2_not_match.accountid IS NULL
This is really late, but it might help some one.
I'll focus only on using the columns we have on the table we are shown (won't combine it with other tables we were not given).
Since the only table in the example is not clearly named, I'll call it some_table
SELECT t.accountidname, t.productname
FROM some_table t
WHERE t.productname IN ('GL','IP')
AND t.accountidname NOT IN (
SELECT accountidname
FROM some_table
WHERE productname = 'MI'
);
The idea here is to:
Select all accountid and productname that have productname either GL or IP (3rd line)
Select all accountid that have a productname MI and remove them from the values we already have (4th line onwards)
With this values, filtering or combining it with other tables should be rather trivial.
You might want to replace the SELECT with SELECT DISTINCT if the combinations of accountid and productname could be repeated in the table.

how to select the last row insert by a specific iduser

Hello I want to get a specific userid who enter specific data. When X user enter data and save h will be the last row. But How I take the last row of exemple my user id = 16. Mnay user can insert data after him but I want only the last row of my user id 16.
SELECT *
from
projetstaches
inner join
timesheets
on (timesheets.timId = projetstaches.prtTimeSheetId)
inner join
users
on (users.usrId = timesheets.timUserId)
WHERE
users.usrId = 16 AND `prtTimeSheetId` = (
SELECT MAX( `prtTimeSheetId` )
FROM projetstaches )
When I do something like this it's return blank cause the last user who entered something is 7.
So how do I retrieve my last user = 16?
Here what look my table ( this is a old ver but good to know how it's look like the data now is more completed but the name of table its the same)
http://pastebin.com/6LBwGtc3
The subquery needs to use a join to select the highest prtTimeSheetId for this user, not the entire table.
SELECT *
from
projetstaches
inner join
timesheets
on (timesheets.timId = projetstaches.prtTimeSheetId)
inner join
users
on (users.usrId = timesheets.timUserId)
WHERE
users.usrId = 16
AND prtTimeSheetId = (
SELECT MAX(preTimeSheetId)
from
projetstaches
inner join
timesheets
on (timesheets.timId = projetstaches.prtTimeSheetId)
inner join
users
on (users.usrId = timesheets.timUserId)
WHERE users.usrId = 16)

MYSQL QUERY Fetching multiple records

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)

Match all records in array in return if record exists MySQL query

I have two table in database.
1) tbl_lab_checkup
2) tbl_lab
tbl_lab has all the records of laboratories and tbl_lab_checkup has all the records o checkup that lab provides.
Following are the fields in tables
1) tbl_lab_checkup
-- labcheckupid (pk)
-- labid (fk)
-- checkupid (fk)
-- cost
-- discount
2) tbl_lab
-- labid (pk)
-- labname
-- labarea (fk)
I have 'areaid'=1 and 'checkupid' in array which I contact with "," (1,2).
What I want is to get all the lablist available in areaid=1 who provides all the checkup in an array (1,2)
I tried following query But Im getting wrong result.
SELECT tlc .* FROM tbl_lab_checkup tlc
INNER JOIN tbl_lab lb ON
tlc.labid = lb.labid
WHERE
tlc.checkupid IN (1,2) AND lb.labarea=1
GROUP BY lb.labid
It return result even if lab provides only one id in array. Anyone have solution for this.
Check fiddle : http://sqlfiddle.com/#!2/5c674/1
If you have building this query then you can add the having clause like following:
SELECT tlc .* FROM tbl_lab_checkup tlc
INNER JOIN tbl_lab lb ON
tlc.labid = lb.labid
WHERE
tlc.checkupid IN (1,2) AND lb.labarea=1
GROUP BY lb.labid
having count(tlc.checkupid) = 2;
Here having count(tlc.checkupid) = 2; the value 2 is the count of your elements in tlc.checkupid IN (1,2).
And if you'd like distinct tlc.checkupid, you could switch the having count(tlc.checkupid) = 2 to having count(distinct tlc.checkupid) = 2;
I would generally go with the suggestion above by vinodadhikary, but another option would be to use one JOIN per check:-
SELECT lb.*
FROM tbl_lab lb
INNER JOIN tbl_lab_checkup tlc1 ON tlc1.labid = lb.labid AND tlc1.checkupid = 1
INNER JOIN tbl_lab_checkup tlc2 ON tlc2.labid = lb.labid AND tlc2.checkupid = 2
WHERE lb.labarea=1
This will work when you want all the tbl_lab_checkup record details
User this code to get your desired result in CI:
$this->db->select("tbl_lab.*");
$this->db->join("tbl_lab_checkup","tbl_lab_checkup.labid = tbl_lab.labid");
$this->db->where("tbl_lab.labarea","1");
$find="FIND_IN_SET('1,2','tbl_lab_checkup.checkupid')";
$this->db->where($find);
$this->db->get("tbl_lab");

Trying to building optimised Query for Group and Subgroup for a user

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).