Current query
SELECT *
FROM employee AS E
INNER JOIN credential AS C ON (C.id = E.credentialId)
LEFT JOIN person AS P ON (C.personId = P.id)
I want to modify this query so that it I just SELECT the employees/credentials which have both loginroles 1 and 2 (loginrole.id).
Relevant tables
loginrole
id
name
credential_has_loginrole
id
credentialId
loginroleId
You can join a subquery, which will return the credential Id's that have both login roles.
SELECT E.*, C.*, P.*
FROM employee AS E
INNER JOIN (
SELECT credentialId
FROM credential_has_loginrole
WHERE loginroleId IN (1,2)
GROUP BY credentialId
HAVING COUNT(DISTINCT loginroleId) = 2
) g ON E.credentialId = g.credentialId
INNER JOIN credential AS C ON (C.id = E.credentialId)
LEFT JOIN person AS P ON (C.personId = P.id)
Update: As per comments, to find employees with either or:
SELECT E.*, C.*, P.*
FROM employee AS E
INNER JOIN (
SELECT credentialId
FROM credential_has_loginrole
WHERE loginroleId IN (1,2)
GROUP BY credentialId
) g ON E.credentialId = g.credentialId
INNER JOIN credential AS C ON (C.id = E.credentialId)
LEFT JOIN person AS P ON (C.personId = P.id)
Alternatively, you can use a JOIN together with DISTINCT:
SELECT DISTINCT E.*, C.*, P.*
FROM employee AS E
INNER JOIN credential AS C ON (C.id = E.credentialId)
INNER JOIN credential_has_loginrole chr
ON E.credentialId = chr.credentialId
AND chr.loginroleId IN (1,2)
LEFT JOIN person AS P ON (C.personId = P.id)
The Scrum Meister's answer is correct. You can alternatively use 2 join trees:
SELECT *
FROM employee AS E
INNER JOIN credential AS c
INNER JOIN credential_has_loginrole chl0 ON (c0.id=chl0.credentialId AND chl0.loginroleId=1)
INNER JOIN credential_has_loginrole chl1 ON (c0.id=chl1.credentialId AND chl1.loginroleId=2)
ON (c.id = E.credentialId)
Related
Sorry, now here is the code, basically, the first query returns me a tab which contains fk_id_produto, i wanted to join it with thee second one with the id_pedido
(SELECT fk_id_produto,fk_id_pedido, descricao_produto, valor_produto
FROM Pedido_Produto
INNER JOIN Produto ON pedido_produto.fk_id_produto = produto.id_produto);
INNER JOIN ON
(SELECT id_cliente,nome_cliente,id_pedido,valor_pedido,data_do_pedido A
FROM Cliente
INNER JOIN Pedido ON cliente.id_cliente = pedido.fk_id_cliente);
You can just do a join with the two selects that you have
SELECT *
FROM
(SELECT 1) as s1 inner join
(SELECT 2) as s2 on s1.id_pedido = s1.fk_id_pedido
SELECT *
FROM
(SELECT
fk_id_produto,
fk_id_pedido,
descricao_produto,
valor_produto
FROM
Pedido_Produto
INNER JOIN Produto
ON pedido_produto.fk_id_produto = produto.id_produto
) as s1
INNER JOIN
(SELECT
id_cliente,
nome_cliente,
id_pedido,
valor_pedido,
data_do_pedido A
FROM
Cliente
INNER JOIN Pedido
ON cliente.id_cliente = pedido.fk_id_cliente
) as s2
ON s1.id_pedido = s1.fk_id_pedido
BR
So you have four tables:
Products (P)
Clients (C)
Orders (O)
OrderProducts (OP)
SELECT
*
FROM
OP
JOIN
P ON P.ID = OP.P_ID
JOIN
O ON O.ID = OP.O_ID
JOIN
C ON C.ID = O.C_ID
That will produce one row for each OP and give you the product, order and client details
I want to convert this query in such a way so it does not have any 'exists' and uses only simple joins.
select t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
from Grades a
left join students s on a.student_ID = s.student_ID
left join Teachers t on t.Teacher_ID = s.Teacher_ID
where 1=1 and t.Teacher_id = 1807600
and exists(
select p.Payment_ID from payments p
inner join lookups l on (l.lookup_id = p.status_id and l.lookup_key in ('condition1','condition2'))
where p.student_ID = a.student_ID
)
I tried something like:
select t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
from Grades a
left join students s on a.student_ID = s.student_ID
left join Teachers t on t.Teacher_ID = s.Teacher_ID
inner join payments p on p.student_ID = a.student_ID
inner join lookups l on (l.lookup_id = p.status_id and l.lookup_key in ('condition1','condition2'))
where 1=1 and t.Teacher_id = 1807600
But I'm not getting the right results. Can you please help. Thanks.
I suppose you could use group by, but this restricts the maintainability of the script for the simple sake of not using EXISTS().
select t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
from Grades a
left join students s on a.student_ID = s.student_ID
left join Teachers t on t.Teacher_ID = s.Teacher_ID
inner join payments p on p.student_ID = a.student_ID
inner join lookups l on (l.lookup_id = p.status_id and l.lookup_key in ('condition1','condition2'))
where t.Teacher_id = 1807600
group by t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
I currently have a DB with 4 table:
Customer
Sale (CustID & RoomID fk)
Room (ManID fk)
Manager
I am trying to get the cities in which the customers reside in as a percentage. However, I only want to show the the customers who made a purchase using a said manager. Currently this comes through as an amount either under or over 100% total.
When this query is isolated to the customer table, the result adds up to 100% correctly, however it does need to be taken from sales using the manager username as a parameter. This is what I currently have:
SELECT
(COUNT(c.city) / (SELECT Count(CustID) FROM Customer) * 100) AS percent, c.city AS City
FROM sale s
INNER JOIN customer c ON s.CustID = c.CustID
INNER JOIN room r ON s.RoomID = r.RoomID
INNER JOIN manager m ON r.ManID = m.ManID
WHERE m.UserName = 'manager123'
GROUP BY c.City;
EDIT:
I wish to add that the CustID may occur more than once within the sales table, additionally, it may be null. Not sure if is required to use distinct when counting.
Having isolated my issue to this, I felt it necessary to mention as I am still unable to exclude these from the result and an incomplete figure (totaling <100% still showing)
Here you go.
SELECT NoCity,COUNT(*)/percent *100 as percentOfCustomerBasedonManager,City
FROM (
SELECT m.UserName,COUNT(c.city) AS NoCity, COUNT(c.CustID) AS percent,c.city AS City FROM
sale s
INNER JOIN customer c ON s.CustID = c.CustID
INNER JOIN room r ON s.RoomID = r.RoomID
INNER JOIN manager m ON r.ManID = m.ManID
GROUP BY c.City ) cityTable WHERE cityTable.UserName = 'manager123'
This may help:
SELECT city, ((city_count)/(customer_count)*100) as Percent
(
SELECT city, COUNT(*) as city_count, customer_count
FROM
(
SELECT distinct c.city
FROM sale s
INNER JOIN customer c ON s.CustID = c.CustID
INNER JOIN room r ON s.RoomID = r.RoomID
INNER JOIN manager m ON r.ManID = m.ManID
WHERE m.UserName = 'manager123'
GROUP BY c.city
) as t1
LEFT JOIN
(
SELECT city as city2, COUNT(*) as customer_count
FROM
(
SELECT c.city, distinct c.CustID
FROM sale s
INNER JOIN customer c ON s.CustID = c.CustID
INNER JOIN room r ON s.RoomID = r.RoomID
INNER JOIN manager m ON r.ManID = m.ManID
WHERE m.UserName = 'manager123'
GROUP BY c.city
) as t2
) as t3 on t1.city=t3.city2
) as master
GROUP BY city
Ok, here is the solution I came to, with a huge thanks to Lim Neo who pointed me in the right direction.
SELECT
round(COUNT(c.city) /
(
SELECT Count(b.CustID)
FROM sale s
INNER JOIN customer c ON s.CustID = c.CustID
INNER JOIN room r ON s.RoomID = r.RoomID
INNER JOIN manager m ON r.ManID = m.ManID
WHERE m.UserName = 'Manager123'
) * 100)
AS percent, c.city AS City
FROM sale s
INNER JOIN customer c ON s.CustID = c.CustID
INNER JOIN room r ON s.RoomID = r.RoomID
INNER JOIN manager m ON r.ManID = m.ManID
WHERE m.UserName = 'Manager123'
GROUP BY c.City;
Table: user
Columns
- id
- username
- full_name
Table: pet
Columns
- id
- pet_name
- color_id
Table: pet_color
Columns
- id
- color
Table: results
Columns
- id
- user_id_1
- user_id_2
- user_id_3
- pet_id
- date
- some_text
This:
SELECT A.id, B.full_name, C.full_name, D.full_name, E.pet_name, A.date, A.some_text
FROM RESULTS AS A
LEFT OUTER JOIN USER AS B ON A.USER_ID1 = B.ID
LEFT OUTER JOIN USER AS C ON A.USER_ID2 = C.ID
LEFT OUTER JOIN USER AS D ON A.USER_ID3 = D.ID
LEFT OUTER JOIN PET AS E ON A.PET_ID = E.ID
will give me almost everything that I want except 'pet_color.color', but I can not figure it out what should I add to the query to get that too.
SELECT A.id, B.full_name, C.full_name, D.full_name, E.pet_name, A.date, A.some_text, pc.color
FROM RESULTS AS A
LEFT OUTER JOIN USER AS B ON A.USER_ID1 = B.ID
LEFT OUTER JOIN USER AS C ON A.USER_ID2 = C.ID
LEFT OUTER JOIN USER AS D ON A.USER_ID3 = D.ID
LEFT OUTER JOIN PET AS E ON A.PET_ID = E.ID
LEFT OUTER JOIN PET_COLOR PC on E.color_id = pc.id
SELECT A.id, B.full_name, C.full_name, D.full_name, E.pet_name, A.date, A.some_text, PC.color
FROM RESULTS AS A
LEFT OUTER JOIN USER AS B ON A.USER_ID1 = B.ID
LEFT OUTER JOIN USER AS C ON A.USER_ID2 = C.ID
LEFT OUTER JOIN USER AS D ON A.USER_ID3 = D.ID
LEFT OUTER JOIN PET AS E ON A.PET_ID = E.ID
LEFT OUTER JOIN PET_COLOR PC ON E.COLOR_ID = PC.ID
Not tried, but this should work
SELECT A.id, B.full_name, C.full_name, D.full_name, E.pet_name, A.date, A.some_text
FROM RESULTS AS A
LEFT OUTER JOIN USER AS B ON A.USER_ID1 = B.ID
LEFT OUTER JOIN USER AS C ON A.USER_ID2 = C.ID
LEFT OUTER JOIN USER AS D ON A.USER_ID3 = D.ID
LEFT OUTER JOIN PET AS E ON A.PET_ID = E.ID
INNER JOIN PET_COLOR PC ON PC.ID = E.COLOR_ID
I have following issue. There are two tables - groups and students and third pivot table group_student.
Query to get students from specific groups (id:1,8) is clear...
SELECT DISTINCT s.*
FROM students AS s
Inner Join group_student AS gs ON gs.student_id = s.id
Inner Join groups AS g ON g.id = gs.group_id
WHERE g.id IN ("1","8")
It works. But, how to query, if I want to select just segment of students of group id 1. For example s.name = "john". So the result should be: all students from group id 8 + all students with name "john" from group id 1.
Thanx for posts :-)
Try this:
SELECT DISTINCT s.*
FROM students AS s
Inner Join group_student AS gs ON gs.student_id = s.id
Inner Join groups AS g ON g.id = gs.group_id
WHERE g.id ="8" or (g.id="1" and s.name = "john")
you can use UNION too
SELECT DISTINCT s.*
FROM students AS s
Inner Join group_student AS gs ON gs.student_id = s.id
Inner Join groups AS g ON g.id = gs.group_id
WHERE g.id = 8
UNION
SELECT DISTINCT s.*
FROM students AS s
Inner Join group_student AS gs ON gs.student_id = s.id
Inner Join groups AS g ON g.id = gs.group_id
WHERE gp.id="1" and s.name = "john"
One more option, avoiding DISTINCT and the (probably unneeded) join to groups:
SELECT s.*
FROM students AS s
WHERE EXISTS
( SELECT *
FROM group_student AS gs
WHERE gs.student_id = s.id
AND ( gs.group_id = 8
OR (gs.group_id, s.name) = (1, 'john')
)
)