Is there any better way to run this query? - mysql

SELECT SQL_NO_CACHE,
b.SID,
b.PID,
a.DateCreated,
a.Batch,
b.Mrp
FROM t1 a INNER JOIN
(
SELECT a.SID, a.PID, Max(a.MRP) AS Mrp
FROM t1 a
WHERE SID IN ('14' , '142', '1420')
GROUP BY a.SID , a.PID
) b
ON a.SID = b.SID AND a.PID = b.PID AND a.Mrp = b.Mrp

Related

I'm doing it when I get an error Error Code: 1248. Every derived table must have its own alias can anyone help me why is it wrong?

SELECT a.telegram_name, a.full_name, a.role_id, a.user_id
from tbl_telegram_user a
LEFT JOIN (
select a.owner_id, a.owner_name from tbl_agenda as a
join (
select a.type, a.message, a.status from tbl_message as a
join tbl_status as b
join (select * from tbl_agenda as a join tbl_message as b
on a.type = b.type
where a.type="/mom" and ( current_date BETWEEN from_time and to_time ) is not null)
on a.status = b.status
where b.status_type = 'workLocation' or b.status_type = 'off') as b
on a.type = b.type
where DATE(a.from_time) = DATE('2021-08-10 21:04:02')) as b
on a.telegram_name = b.owner_name
where b.owner_name is null AND a.user_id <> 0
i think in line 9 you forget alias :
SELECT a.telegram_name, a.full_name, a.role_id, a.user_id from tbl_telegram_user a LEFT JOIN ( select a.owner_id, a.owner_name from tbl_agenda as a join ( select a.type, a.message, a.status from tbl_message as a join tbl_status as b join (select * from tbl_agenda as a join tbl_message as b on a.type = b.type where a.type="/mom" and ( current_date BETWEEN from_time and to_time ) is not null) as "your alias" on a.status = b.status where b.status_type = 'workLocation' or b.status_type = 'off') as b on a.type = b.type where DATE(a.from_time) = DATE('2021-08-10 21:04:02')) as b on a.telegram_name = b.owner_name where b.owner_name is null AND a.user_id <> 0
Seems alias was missing to sub query. Try below query.
SELECT a.telegram_name, a.full_name, a.role_id, a.user_id
from tbl_telegram_user a
LEFT JOIN (
select a.owner_id, a.owner_name from tbl_agenda as a
join (
select a.type, a.message, a.status from tbl_message as a
join tbl_status as b
join (select * from tbl_agenda as a join tbl_message as b
on a.type = b.type
where a.type="/mom" and ( current_date BETWEEN from_time and to_time ) is not null) as a
on a.status = b.status
where b.status_type = 'workLocation' or b.status_type = 'off') as b
on a.type = b.type
where DATE(a.from_time) = DATE('2021-08-10 21:04:02')) as b
on a.telegram_name = b.owner_name
where b.owner_name is null AND a.user_id <> 0

MYSQL join not bringing correct result

I have created the following query which includes 2 joins and is working fine:
SELECT a.name, b.tid
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
WHERE b.status = 'FAIL';
The output is coming as follows:
id tid name
17695 19512 abc.com
17781 19628 abc1.com
17805 19732 abc2.com
17806 19703 abc3.com
17807 19704 abc4.com
I have another table table3 which has following values
id tid name details
842 19512 abc.com Details Description 1
843 19628 abc1.com Details Description 2
I want to join the above query with table3 on tid such that I get the following output
id tid name details
17695 19512 abc.com Details Description 1
17781 19628 abc1.com Details Description 1
I am using the following query but it is returning only one row which is not correct
SELECT a.name, b.tid
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table3 T3 on b.tid = T3.tid
WHERE b.status = 'FAIL'
Make your query a sub-query and join it to the table
WITH BASELINE AS
(
SELECT a.name AS name, b.tid AS tid
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
WHERE b.status = 'FAIL';
)
-------------------------------------------------------------------
SELECT
base.tid
, base.name
, t3.details
FROM
BASELINE base
LEFT JOIN
Table3 t3
ON base.tid = t3.tid
Is not the neatest solution but it always works for me

MYSQL Using Union to combine two queries

My first query looks as below
SELECT a.name, b.desc, T3.desc1 as Output
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table3 T3 on b.tid = T3.tid
WHERE b.status = 'FAIL'
AND b.type = 'Type1'
My second query looks as below
SELECT a.name, b.desc, T4.desc2 as Output
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table4 T4 on b.tid = T4.tid
WHERE b.status = 'FAIL'
AND b.type = 'Type2'
In my final result I want Output column which will have values either from T3.desc1 or T4.desc2
How can I use UNION to combine both queries into a single query?
just put UNION ALL between the queries. Youll have to alias the columns
Do this:
Query1 UNION Query2; -- for union without duplicates (the set union as in maths)
OR
Query1 UNION ALL Query2; -- for union with duplicates
So it should be:
SELECT a.name, b.desc, T3.desc1 as Output
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table3 T3 on b.tid = T3.tid
WHERE b.status = 'FAIL'
AND b.type = 'Type1'
UNION
SELECT a.name, b.desc, T4.desc2 as Output
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table4 T4 on b.tid = T4.tid
WHERE b.status = 'FAIL'
AND b.type = 'Type2';

MySQL combining two queries into single query

My first query looks as below
SELECT a.name, b.desc, T3.desc1 as Output
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM q_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table3 T3 on b.tid = T3.tid
WHERE b.status = 'FAIL'
My second query looks as below
SELECT a.name, b.desc, T4.desc2 as Output
FROM table1 a INNER JOIN
table2 b
ON a.id = b.id
INNER JOIN (
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM q_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
INNER JOIN table4 T4 on b.tid = T4.tid
WHERE b.status = 'FAIL'
In my final result I want Output column which will have values either from T3.desc1 or T4.desc2
How can I combine both queries into a single query?
If the table2.id exists in one of the tables - table3 or table4, a LEFT JOIN will simplify the query with the help of IFNULL().
SELECT a.name,
b.desc,
IFNULL(T3.desc1, T4.desc2) as Output
FROM table1 a
INNER JOIN table2 b ON a.id = b.id
INNER JOIN
(
SELECT b2.id, b2.status, MAX(b2.created_time) as max_time
FROM oac.qualys_scan b2
GROUP BY b2.id , b2.qualys_type
) t on t.id = a.id
AND t.status=b.status
AND t.max_time = b.created_time
LEFT JOIN table3 T3 on b.tid = T3.tid
LEFT JOIN table4 T4 on b.tid = T4.tid
WHERE b.status = 'FAIL'

Getting an error when using joins in query

I have this query:
SELECT * FROM `employee_activities` a
LEFT JOIN `activity` b ON a.activity_code = b.code
LEFT JOIN `employees` c ON a.employee_code = c.code
WHERE b.type = "Design"
AND c.code NOT IN(
SELECT * FROM `employee_activities` a
LEFT JOIN `activity` b ON a.activity_code = b.code
LEFT JOIN `employees` c ON a.employee_code = c.code
WHERE b.type = "Testing"
)
GROUP BY c.code
I get this error:
#1241 - Operand should contain 1 column(s)
I'm tying to get all employees that have at least one activity of type "Design" and None activity of type "Testing".
I have a query that works but I would like it to work with joins.
This works:
SELECT c.name FROM `employee_activities` a, `activity` b, `employees` c
WHERE a.activity_code = b.code
AND a.employee_code = c.code
AND b.type = "Design"
AND c.code NOT IN(
SELECT c.code FROM `employee_activities` a, `activity` b, `employees` c
WHERE a.activity_code = b.code
AND a.employee_code = c.code
AND b.type = "Testing"
)
GROUP BY c.code
What did I do wrong on the sql with joins?
For the not in sub query - it should contain only one column - for example
SELECT * FROM `employee_activities` a
LEFT JOIN `activity` b ON a.activity_code = b.code
LEFT JOIN `employees` c ON a.employee_code = c.code
WHERE b.type = "Design"
AND c.code NOT IN(
SELECT b.employee_code FROM `employee_activities` a
LEFT JOIN `activity` b ON a.activity_code = b.code
LEFT JOIN `employees` c ON a.employee_code = c.code
WHERE b.type = "Testing"
)
GROUP BY c.code
Your query
AND c.code NOT IN(
SELECT * FROM `employee_activities` a
...
tries to compare c.code to all columns in the subquery. What you want is probably;
AND c.code NOT IN(
SELECT c.code FROM `employee_activities` a
Also, you have a problem in your LEFT JOIN;
LEFT JOIN `activity` b ON a.activity_code = b.code
...
WHERE b.type = "Design"
When you compare a column that is left joined in into a WHERE clause, it basically turns the whole join into an INNER JOIN. Since your original query seems to use an inner join, that should be ok, but you may as well change it to;
SELECT * FROM `employee_activities` a
JOIN `activity` b ON a.activity_code = b.code AND b.type='Design'
LEFT JOIN `employees` c ON a.employee_code = c.code
Your problem is in this part:
AND c.code NOT IN(
SELECT * FROM
You can't have an * here as its looking to see if c.code is in the list of field values returned and must specify just a single field in the select.
The problem is in this section:
AND c.code NOT IN(
SELECT * FROM `employee_activities` a
You can't SELECT * in that nested query. You need to select exactly one column that will be compared to the c.code. You need this instead:
AND c.code NOT IN(
SELECT c.code FROM `employee_activities` a
DO this:
SELECT * FROM `employee_activities` a
LEFT JOIN `activity` b ON a.activity_code = b.code
LEFT JOIN `employees` c ON a.employee_code = c.code
WHERE b.type = "Design"
AND c.code NOT IN(
SELECT c.code FROM `employee_activities` a
LEFT JOIN `activity` b ON a.activity_code = b.code
LEFT JOIN `employees` c ON a.employee_code = c.code
WHERE b.type = "Testing"
)
GROUP BY c.code
As here you should compare the data with code column and * will fetch all the records.