MySQL multiple level subquery - mysql

I try to use a field from joined table "glpi_items_tickets" into a subquery like this :
SELECT
NAME
FROM
(
SELECT
NAME
FROM glpi_computers
WHERE id = git.items_id
) AS t1
UNION
(
SELECT
NAME
FROM glpi_monitors
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_networkequipments
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_printers
WHERE id = git.items_id
)
) AS aliasIT
but i have an error of type : "#1054 - Unknown Column 'git.items_id' in where clause"
The entire request :
SELECT
gt.id,
(
SELECT
NAME
FROM
(
SELECT
NAME
FROM glpi_computers
WHERE id = git.items_id
) AS t1
UNION
(
SELECT
NAME
FROM glpi_monitors
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_networkequipments
WHERE id = git.items_id
)
UNION
(
SELECT
NAME
FROM glpi_printers
WHERE id = git.items_id
)
) AS aliasIT
FROM glpi_tickets gt
INNER JOIN glpi_items_tickets git
ON gt.id = git.tickets_id;
Do you have a solution for used the field "glpi_items_tickets.items_id" into my subqueries?

SELECT ...
FROM
glpi_tickets gt
INNER JOIN glpi_items_tickets git
ON git.tickets_id = gt.id;
INNER JOIN
(
SELECT NAME, id FROM glpi_computers
UNION
SELECT NAME, id FROM glpi_monitors
UNION
SELECT NAME, id FROM glpi_networkequipments
UNION
SELECT NAME, id FROM glpi_printers
) g
ON g.id = git.items_id

Use the full table name instead of the alias.
Replace every git.items_id with glpi_items_tickets.items_id.
The alias does not exist during the compilation of the subquery, since the outer query (where you set your alias) can not be compiled until the inner querys are considered valid.

Related

Need json value without re-joining the table in SQL Server

I have written the code shown below and I got the expected output. but,need the same output without use the same tables in inline view (such as tables join for UserPhoneDetail_JSON). thanks in advance
Code:
BEGIN
DROP TABLE #USERMASTER;
DROP TABLE #USERPHONE;
CREATE TABLE #USERMASTER (ID INT, NAME VARCHAR(100));
CREATE TABLE #USERPHONE (ID INT, PHONENUMBER NUMERIC,PHONETYPE CHAR(1));
INSERT INTO #USERMASTER VALUES(1,'JOHN');
INSERT INTO #USERMASTER VALUES(2,'VICTOR');
INSERT INTO #USERPHONE VALUES(1,1356487965,'W');
INSERT INTO #USERPHONE VALUES(1,9841007493,'M');
INSERT INTO #USERPHONE VALUES(1,7255952105,'O');
INSERT INTO #USERPHONE VALUES(2,9874563212,'M');
WITH E AS (SELECT A.ID,A.NAME,B.PHONENUMBER,B.PHONETYPE,ROW_NUMBER() OVER(PARTITION BY A.ID ORDER BY A.ID) RN
FROM #USERMASTER A JOIN #USERPHONE B ON A.ID=B.ID)
SELECT E.ID,
E.NAME,
E.PHONENUMBER,
E.PHONETYPE,
UserPhoneDetail_JSON = (
SELECT A.ID,B.PHONETYPE,PHONENUMBER,A.NAME FROM #USERMASTER A JOIN #USERPHONE B ON A.ID=B.ID
FOR JSON PATH )
FROM E WHERE RN=1;
END
output:
1 JOHN 1356487965 W [{"ID":1,"PHONETYPE":"W","PHONENUMBER":1356487965,"NAME":"JOHN"},{"ID":1,"PHONETYPE":"M","PHONENUMBER":9841007493,"NAME":"JOHN"},{"ID":1,"PHONETYPE":"O","PHONENUMBER":7255952105,"NAME":"JOHN"},{"ID":2,"PHONETYPE":"M","PHONENUMBER":9874563212,"NAME":"VICTOR"}]
2 VICTOR 9874563212 M [{"ID":1,"PHONETYPE":"W","PHONENUMBER":1356487965,"NAME":"JOHN"},{"ID":1,"PHONETYPE":"M","PHONENUMBER":9841007493,"NAME":"JOHN"},{"ID":1,"PHONETYPE":"O","PHONENUMBER":7255952105,"NAME":"JOHN"},{"ID":2,"PHONETYPE":"M","PHONENUMBER":9874563212,"NAME":"VICTOR"}]
EXPECTED OUTPUT:
1 JOHN 1356487965 W [{"ID":1,"PHONETYPE":"W","PHONENUMBER":1356487965,"NAME":"JOHN"},{"ID":1,"PHONETYPE":"M","PHONENUMBER":9841007493,"NAME":"JOHN"},{"ID":1,"PHONETYPE":"O","PHONENUMBER":7255952105,"NAME":"JOHN"}]
2 VICTOR 9874563212 M [{"ID":2,"PHONETYPE":"M","PHONENUMBER":9874563212,"NAME":"VICTOR"}]
If I understand you correctly and you need to generate JSON content for each first row per ID, this statement is an option:
SELECT
t.ID, t.NAME, t.PHONENUMBER, t.PHONETYPE,
UserPhoneDetail_JSON = (
SELECT t.ID, PHONETYPE, PHONENUMBER, t.NAME
FROM #USERPHONE
WHERE ID = t.ID
FOR JSON PATH
)
FROM (
SELECT
m.ID, m.NAME, p.PHONENUMBER, p.PHONETYPE,
ROW_NUMBER() OVER (PARTITION BY m.ID ORDER BY p.ID) RN
FROM #USERMASTER m
JOIN #USERPHONE p ON m.ID = p.ID
) t
WHERE t.RN = 1

Cross Apply in MySQL

This is my sql in SQL Server. How can I achieve this in MySQL?
SELECT COUNT(*) as total FROM (SELECT personal.*
CROSS APPLY
(
SELECT TOP 1 educ_attain.school
FROM educ_attain
WHERE personal.empno = educ_attain.empno
) educ
WHERE personal.status = 'ACTIVE'
) as num
My goal is to exclude employees who doesn't have a record in educ_attain. I have tried using sub-query but still returning employees with no record.
You can try any of these following-
SELECT *
FROM personal
INNER JOIN educ_attain
ON personal.empno = educ_attain.empno
WHERE personal.status = 'ACTIVE'
OR
SELECT *
FROM personal
WHERE empno IN
(
SELECT DISTINCT empno FROM educ_attain
)
AND status = 'ACTIVE'
To get count - Just use SELECT COUNT(*) for any of the above query.
Not Exists, employees do not have record in eductable then show
select * from
employee e
where not exists
(
select 1 from eductable t
on e.emp_id = t.emp_id
)

multiple distinct from multiple tables

MySQL request is:
SELECT DISTINCT a.field_department_color_value, DISTINCT a.nid, DISTINCT c.nid, DISTINCT c.field_oeuvre_notice_bibliography_value, DISTINCT c.field_oeuvre_notice_author_value, DISTINCT d.field_oeuvre_cartel_dimension_value, DISTINCT d.field_oeuvre_cartel_origin_value
FROM (
SELECT DISTINCT field_department_color_value,nid
FROM content_type_department) a,
( SELECT field_oeuvre_notice_dep_value
FROM content_field_oeuvre_notice_dep) b,
( SELECT field_oeuvre_notice_bibliography_value, field_oeuvre_notice_author_value, field_oeuvre_notice_cartel_nid
FROM content_type_oeuvre_notice) c,
( SELECT field_oeuvre_cartel_dimension_value, field_oeuvre_cartel_origin_value, nid
FROM content_type_oeuvre_cartel) d,
WHERE a.nid = b.field_oeuvre_notice_dep_value
AND d.nid = c.field_oeuvre_notice_cartel_nid
AND a.field_department_color_value LIKE 'greek'
LIMIT 0 , 8
it takes distinct just for the attribute field_department_color_value! while I want to do it for all the attributes in the SELECT section... Thank you
Try
SELECT DISTINCT a.field_department_color_value,
a.nid,
c.nid,
c.field_oeuvre_notice_bibliography_value,
c.field_oeuvre_notice_author_value,
d.field_oeuvre_cartel_dimension_value,
d.field_oeuvre_cartel_origin_value
FROM (
SELECT DISTINCT field_department_color_value,nid
FROM content_type_department) a,
( SELECT field_oeuvre_notice_dep_value
FROM content_field_oeuvre_notice_dep) b,
( SELECT field_oeuvre_notice_bibliography_value, field_oeuvre_notice_author_value, field_oeuvre_notice_cartel_nid
FROM content_type_oeuvre_notice) c,
( SELECT field_oeuvre_cartel_dimension_value, field_oeuvre_cartel_origin_value, nid
FROM content_type_oeuvre_cartel) d,
WHERE a.nid = b.field_oeuvre_notice_dep_value
AND d.nid = c.field_oeuvre_notice_cartel_nid
AND a.field_department_color_value LIKE 'greek'
LIMIT 0 , 8

Every derived table must have its own alias error in MySQL

I have the following query:
SELECT SUM( cost )
FROM (
SELECT s.cost
FROM sandwiches AS s
WHERE s.name = "Cheese Steak"
)
UNION (
SELECT p.cost
FROM pizza AS p
WHERE TYPE = "Plain"
AND SIZE = "L"
)
That gives me an error of:
#1248 - Every derived table must have its own alias
You need to alias your temp tables
SELECT SUM( cost )
FROM
(
(
SELECT s.cost
FROM sandwiches AS s
WHERE s.name = "Cheese Steak"
) AS T1
UNION
(
SELECT p.cost
FROM pizza AS p
WHERE TYPE = "Plain"
AND SIZE = "L"
) AS T2
) AS T
Do you want the whole Sum?
SELECT
( SELECT SUM(s.cost)
FROM sandwiches AS s
WHERE s.name = "Cheese Steak"
)
+
( SELECT SUM(p.cost)
FROM pizza AS p
WHERE p.TYPE = "Plain"
AND p.SIZE = "L"
)
The following form should do the job:
SELECT SUM(cost) FROM (
SELECT cost FROM sandwiches WHERE name = "Cheese Steak"
UNION
SELECT cost FROM pizza WHERE TYPE = "Plain" AND SIZE = "L"
) as temp
MySQL only requires a temporary table name for the subselect.

MySQL Update Inner Join Aliases

I'm trying to run this query:
UPDATE anothertable
INNER JOIN (SELECT *,
LEAST(table1.from_price, table2.from_price, table3.from_price) AS cheapestPrice
FROM (SELECT * FROM table1 v WHERE hotelid >= 1
UNION
SELECT * FROM table2 c WHERE hotelid >= 1
UNION
SELECT * FROM table3 k WHERE hotelid >= 1) AS temp
GROUP BY temp.hotelid, temp.country) AS i ON anothertable.id = i.hotelid
AND anothertable.country = i.country
SET price = i.cheapestPrice,
op = i.to
However I cannot get the LEAST function to get access to a field called "from_price".
Ideas?
You should use Min instead of Least:
Update anothertable
Join (
Select hotelid, country, to
, Min(from_price) AS cheapestPrice
From (
Select hotelid, country, from_price, to
From table1 v
Where hotelid >= 1
Union
Select hotelid, country, from_price, to
From table2 c
Where hotelid >= 1
Union
Select hotelid, country, from_price, to
From table3 k
Where hotelid >= 1
) AS temp
Group By temp.hotelid, temp.country, temp.to
) As i
On anothertable.id = i.hotelid
And anothertable.country = i.country
Set price = i.cheapestPrice
, op = i.to
Edit
As pointed out in comments, I omitted the to column from the inner temp query. However, it occurs to me that it isn't clear how to should be included because you are using an awful feature of MySQL with respect to declaring the Group By columns. I'm assuming that you need to include to in the Group By however if that is not the case, you should be explicit about what aggregate function it should use on the to column.
Here's an alternate where I use Min on the to column:
Update anothertable
Join (
Select temp.hotelid, temp.country
, Min(temp.to) As to
, Min(temp.from_price) AS cheapestPrice
From (
Select v.hotelid, v.country, v.from_price, v.to
From table1 v
Where hotelid >= 1
Union
Select c.hotelid, c.country, c.from_price, c.to
From table2 c
Where hotelid >= 1
Union
Select k.hotelid, k.country, k.from_price, k.to
From table3 k
Where hotelid >= 1
) AS temp
Group By temp.hotelid, temp.country
) As i
On anothertable.id = i.hotelid
And anothertable.country = i.country
Set price = i.cheapestPrice
, op = i.to