mysql retrieving unique id from table with division - mysql

In a table like this
ID | Category | Value
1 Device Computer
1 Location 1st Floor
2 Device Phone
2 Type Voip
2 Location 1st Floor
3 Device Computer
3 Location 2nd Floor
How do I get the ID of the where device='computer' and location='1st Floor'? The query is created programmatically and there might be many of these criteria that specifies a single ID in a statement.

You can use the join query like this for your problem.
select a.ID from MYTABLE a, MYTABLE b where a.ID=b.ID and a.Category='Device'
and a.VALUE='Computer' and b.Category='Location' and b.VALUE='1st Floor';
If there is may catogories like this then you must split the table like below.
TABLES :
Category with columns (CATOGORY_ID, CATOGORY)
Value with columns (VALUE_ID, VALUE)
MYTABLE with columns (ID, CATOGORY_ID, VALUE_ID)
then you should use join query.

select Distinct a.id
from myTable a inner join myTable b
on a.Id = b.Id
Where a.value = 'Computer' And b.value = '1st Floor' and a.Category = 'Device' and b.Category = 'Location'
Demo here

Related

Count rows nin a column from one table do not appear in another table

I have TableA with 5 rows in column siteID ( so 5 different sites).
I have TableB that stores userIDs and which sites they have access to. I need to take all 5 siteIDs from TableA and check to see if any of the siteIDs are NOT in TableB for a specific user.
I'm trying something similar to this pseudocode but not sure how the syntax should go:
SET #invalidSites = (
SELECT COUNT(*)
FROM userSiteAccess AS usa
RIGHT JOIN customer.sitesVsUsers AS cust
ON usa.listOfSites = cust.siteID
WHERE cust.siteID IS NULL);
EXAMPLE:
TABLE A
listOfSites
1
2
3
TableB
userID siteAccess
50 3
The count should return 2 as the list of sites has 2 additional rows (site 1 and site 2) but the user only has access to site 3.
You need to use LEFT JOIN rather than RIGHT JOIN, and you need to specify the user ID in the ON condition.
SELECT COUNT(*)
FROM userSiteAccess AS usa
LEFT JOIN sitesVsUsers AS cust
ON usa.listOfSites = cust.siteID AND cust.userId = 2
WHERE cust.siteID IS NULL
DEMO
With NOT EXISTS:
select count(*) counter
from tablea a
where not exists (
select 1 from tableb
where userid = 50 and siteaccess = a.listofsites
)

select record only if specific related values are provided in mysql

I 3 have tables, 2(A and B) of them have many to many relationship, they connected through pivot C table. tables desc:
A(id, name)
B(id, is_required)
C(a_id, b_id)
I want to select records from A table, which related record ids from B table are in provided input and fit some condition. for example:
lest say I have list of integers(ids) [1,2,3,4,8,12] and also one record from A has 5 related records from B, example:
A
id name
1 test
-------------
B
id is_required
1 true
2 true
3 false
10 false
16 false
I need to select records from table A join related records from table B, and check - if all required(is_required = true) record ids from B exists in my list ([1,2,3,4,8,12]) then we select this record, otherwise not. so the first example should be selected, because all required records from B (1 and 2) exists in list. for example this:
A
id name
2 test2
-------------
B
id is_required
1 true
2 true
5 true
6 false
should not be selected, because required record with id 5 not provided in list. how can I implement this in mysql? query example:
SELECT A.id, A.name FROM A, B, C
WHERE A.id = C.a_id
AND C.b_id = B.id
as you see, for now its only joins related data, I really don't know how should I implement this. can you please help me?
I believe that you need NOT EXISTS
select A.*
from A
where not exists(
select 1
from C
join B on C.b_id = B.id and
A.id = C.a_id and
is_required = 'false'
)
You can use group by and having:
select c.a_id
from c join
b
on c.b_id = b.id and b.is_required = 'true'
group by c.a_id
having count(*) = (select count(*) from b where b.is_required = 'true');

MySQL join to get a single row using order/priority

I have a couple tables in MySQL DB
EID Name
1 Title A
2 Title B
3 Title C
LID EID Location Address Order
1 1 Office NY 1
2 1 Home IL 2
3 2 Office CA 1
4 3 Home NJ 2
I have the above 2 tables (Employee and Location). I would like to know the location of each Employee with office as a preferred choice and if 'office' does not exist then would need 'Home' location . The order column defined the order/priority of what is needed.
here is the output needed
EID LID Name Location Address
1 1 Title A Office NY
2 3 Title B Office CA
3 4 Title C Home NJ
The first join of the query below just connects the Employee and Location tables, but note that it results in all records from Location being joined. The critical part of the below query is the second INNER JOIN to a subquery. This subquery identifies the minimum (i.e. highest priority) order for each employee ID. This is then used to discard records from the first join which are not the highest priority.
SELECT t1.EID,
t2.LID,
t1.Name,
t2.Location,
t2.Address
FROM Employee t1
INNER JOIN Location t2
ON t1.EID = t2.EID
INNER JOIN
(
SELECT EID, MIN(`Order`) AS min_order
FROM Location
GROUP BY EID
) t3
ON t2.EID = t3.EID AND
t2.Order = t3.min_order
One other note: Don't name your columns Order, which is a MySQL keyword. To get my query to work, I had to put it in backticks, which is inconvenient to say the least, and possibly error prone.
Demo here:
SQLFiddle
There are two posibility to get your result.
1)If you need Based on Order result then use this query
SELECT e1.EID, l1.LID, e1.Name, l1.Location, l1.Address
FROM Employee e1
JOIN
(SELECT MIN(`Order `) as Minorder, EID, LID, Location, Address, Order
FROM Location l1
GROUP BY EID) l1
ON l1.EID = e1.EID AND l1.Minorder = l1.Order;
2)if you need result Based on EID then use this query
SELECT e1.EID,l1.LID,e1.Name,l1.Location,l1.Address
FROM Employee e1 JOIN
(SELECT MIN(`EID`)as Mineid,EID,LID,Location,Address,`Order` FROM Location l1 GROUP BY EID)l1
ON l1.Mineid = e1.EID;
Extra Note:-
Plese donot use mysql inbuilt keyword as Column name or Table name for more information read this link click here
You can the expected result by using inner join
Select a.eid,b.Lid,a.name,b.location,b.address from Table1 a innner join (select * from Tableb group by eid) b on
a.eid=b.eid;
you can try this code this will help you as i think
select E.EID,E.name,ad.LID,ad.LOCATION,ad.ADDRESS,ad.[order]
from #emp E inner join #address ad on E.EID = ad.EID
inner join (select EID, min([order]) [order]
from #address
group by EID) tt on ad.EID = tt.EIDand ad.[order] = tt.[order]

how to get Intersection of two query in mysql

I have a table that has two column with two foreign key from two different table.
this is my relation table:
I want to select those student who can speak both language with id 3 and 4.
How can i wrote a query to give me for e.x 12 , 14
You can give it a try:
SELECT
student_id,
COUNT(*) total
FROM your_table
WHERE language_id IN (3,4)
GROUP BY student_id
HAVING COUNT(*) = 2;
Only IN doesn't ensure that a student is involved both in language id 3 & 4.
You need to use GROUP BY student_id HAVING COUNT(*) = 2 in order to ensure those student_ids to be in the result who were involved both in language id 3 & 4
Another solution would be using INNER JOIN. But it doesn't scale.
SELECT
A.student_id
FROM your_table A
INNER JOIN your_table B ON A.student_id = B.student_id
AND A.language_id = 3 AND B.language_id = 4
Assume your relation is named "my-relation":
SELECT R1.student_Id FROM my-Relation R1 join my-Relation R2 on R1.student_id = R2.student_id where R1.language_Id = '3' and R2.language_id = '4'

Concat foreign key values from a self related table

I have a products database which has a multi-tier category structure. Products are assigned to a category. The category table looks like this:
id name parent_id
================================
1 Electronics NULL
2 AV 1
3 Speakers 2
4 Wireless 3
What I want to do is, as part of my SELECT statement for products, output a concatenated string of the category tree.
The product is always assigned to the last category, so for example, Product "500w Wireless Speakers" would be assigned to category_id 4 (based on the above).
The ouputted column should be Electronics-AV-Speakers-Wireless.
Is this possible to do? I have looked at GROUP_CONCAT() but I'm having trouble working out the correct syntax.
Join as many times as you need, and concat the names:
select concat(a.name, '-', b.name, '-', c.name, '-', d.name) name
from mytable a
join mytable b on a.id = b.parent_id
join mytable c on b.id = c.parent_id
join mytable d on c.id = d.parent_id;