PIVOT data in mysql - mysql
RCDID, EmployeeID, LogDate, LogTime, TerminalID, InOut, read
3079184, 'A00075', '2009/10/28', '07:17:10 ', 'VC01 ', 'IN ', '1'
3079185, 'A00075', '2009/10/28', '17:28:51 ', 'VC01 ', 'OUT ', '1'
3079186, 'A00038', '2009/10/28', '07:29:17 ', 'VC01 ', 'IN ', '1'
3079187, 'A00038', '2009/10/28', '17:30:05 ', 'VC01 ', 'OUT ', '1'
3079188, 'A00085', '2009/10/28', '07:37:34 ', 'VC01 ', 'IN ', '1'
3079189, 'A00085', '2009/10/28', '17:43:14 ', 'VC01 ', 'IN ', '1'
Hi, above is my source table (mysql) i want to cross tab the data as follows.
EmployeeID, LogDate, In_location, in_time, Out_location, Out_time
'A00001', '2009/10/28', 'VC01', '08:37:55 ', '', '',
'A00001', '2009/10/29', 'VC01', '08:09:57 ', 'VC01 ', '17:09:32 '
'A00001', '2009/10/30', 'VC01 ', '09:48:41 ', 'VC01 ', '20:40:37 '
'A00001', '2009/11/03', 'VC01', '08:20:34 ', 'VC01 ', '18:03:34 '
'A00001', '2009/11/04', 'VC01 ', '08:26:49 ', 'VC01 ', '19:21:46 '
'A00001', '2009/11/05', 'VC01', '08:16:00 ', 'VC01 ', '19:26:01 '
can somebody help me please. i am really appreciate your help
Essentially, one needs to perform a self-join to pair up movements IN with the following OUT by the same employee on the same date:
SELECT a.EmployeeID, a.LogDate,
a.LogTime AS In_time,
MIN(b.LogTime) AS Out_time
FROM my_table a LEFT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND b.InOut = 'OUT'
WHERE a.InOut = 'IN'
GROUP BY EmployeeID, LogDate, In_time
However, this excludes situations where there is an IN record with no corresponding OUT record. Since MySQL has no native support for FULL OUTER JOIN, one must instead use UNION to combine the above with a similar query that pairs movements OUT with the preceding IN by the same employee on the same date:
SELECT a.EmployeeID, a.LogDate,
a.LogTime AS In_time,
MIN(b.LogTime) AS Out_time
FROM my_table a LEFT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND b.InOut = 'OUT'
WHERE a.InOut = 'IN'
GROUP BY EmployeeID, LogDate, In_time
UNION
SELECT a.EmployeeID, a.LogDate,
MAX(a.LogTime) AS In_time,
b.LogTime AS Out_time
FROM my_table a RIGHT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND a.InOut = 'IN'
WHERE b.InOut = 'OUT'
GROUP BY EmployeeID, LogDate, Out_time
Having obtained this detail, one then needs to join the result with the table again in order to extract the terminals on which the movements were logged:
SELECT t.EmployeeID,
t.LogDate,
a.TerminalID AS In_location,
t.In_time,
b.TerminalID AS Out_location,
t.Out_time
FROM (
SELECT a.EmployeeID, a.LogDate,
a.LogTime AS In_time,
MIN(b.LogTime) AS Out_time
FROM my_table a LEFT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND b.InOut = 'OUT'
WHERE a.InOut = 'IN'
GROUP BY EmployeeID, LogDate, In_time
UNION
SELECT a.EmployeeID, a.LogDate,
MAX(a.LogTime) AS In_time,
b.LogTime AS Out_time
FROM my_table a RIGHT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND a.InOut = 'IN'
WHERE b.InOut = 'OUT'
GROUP BY EmployeeID, LogDate, Out_time
) t
LEFT JOIN my_table a ON
a.EmployeeID = t.EmployeeID
AND a.LogDate = t.LogDate
AND a.LogTime = t.In_time
AND a.InOut = 'IN'
LEFT JOIN my_table b ON
b.EmployeeID = t.EmployeeID
AND b.LogDate = t.LogDate
AND b.LogTime = t.Out_time
AND b.InOut = 'OUT'
See it on sqlfiddle.
Related
Convert mysql to doctrine
I have the following MySQL query select a.*, d.*, p.*, pow.* from appointment a left join doctor d on d.id = a.doctor_id left join patient p on p.id = a.patient_id left join point_of_work pow on pow.id = a.point_of_work_id where (doctor_id, patient_id, date) = ( select doctor_id, patient_id, coalesce( min(case when date > curdate() then date end), max(case when date < curdate() then date end) ) date from appointment where (doctor_id, patient_id) = (a.doctor_id, a.patient_id) ) and d.external_id = 1 And I am trying to convert it to DQL. Right now I come to this version of DQL but it seems I'am doing something (or maybe more things:( wrong) $expr = $this->getEntityManager()->getExpressionBuilder(); $queryBuilder = $this->createQueryBuilder('a') ->leftJoin(Doctor::class, 'd') ->leftJoin(Patient::class, 'p') ->leftJoin(PointOfWork::class, 'pow') ->where( $expr->eq('doctorId, patient_id, date', $this->createQueryBuilder('a') ->select(Appointment::class . ', coalesce( min(case when date > curdate() then date end), max(case when date < curdate() then date end) ) date' ) ->where ('(doctorId, patientId) = (a.doctorId, a.patientId)') ) ) ->andWhere('d.externalId = :externalId') ->setParameter('externalId', $doctorExternalId) ->setMaxResults($limit) ->setFirstResult($offset); What approaches do I need for the DQL conversion?
Get parent column in 3rd-level subquery
How can I get a column from the top-most parent query in a subquery within a subquery? Do I have to pass it like a variable? Here's my code: SELECT c.in_customer_id, ( SELECT group_concat(the_schedule separator '\r\n') FROM ( SELECT concat_ws('\n', 'Route: ', s.route_id, 'Interval: ', s.service_interval, 'Week No.: ', s.week_no, 'Weekdays: ', s.weekdays, 'Start Date: ', s.start_date, 'End Date: ', s.end_date, 'Start Time: ', s.start_time, 'End Time: ', s.end_time, '\n') AS the_schedule FROM schedule s WHERE s.service_address_id IN ( SELECT in_customer_address_id FROM tbl_customer_address a2 WHERE a2.in_customer_id = c.in_customer_id ) AND s.is_skipped = '0' GROUP BY s.service_address_id ) a ) AS "Schedule" FROM tbl_customers c The response I get is "Error Code: 1054. Unknown column 'c.in_customer_id' in 'where clause'"
As a principle, you want to move the sub-queries in to your FROM clause. Try something like this... SELECT c.in_customer_id, s.grouped_schedule FROM tbl_customers AS c LEFT JOIN ( SELECT in_customer_id, group_concat(the_schedule separator '\r\n') AS grouped_schedule FROM ( SELECT a.in_customer_id, a.in_customer_address_id, concat_ws('\n', 'Route: ', s.route_id, 'Interval: ', s.service_interval, 'Week No.: ', s.week_no, 'Weekdays: ', s.weekdays, 'Start Date: ', s.start_date, 'End Date: ', s.end_date, 'Start Time: ', s.start_time, 'End Time: ', s.end_time, '\n') AS the_schedule FROM tbl_customer_address AS a INNER JOIN schedule AS s ON s.service_address_id = a.in_customer_address_id WHERE s.is_skipped = 0 ) AS schedules GROUP BY in_cusomer_id ) AS s ON s.in_customer_id = c.in_customer_id
Combining all data with a unique ID - MySQL
I have this data that I got from my current query. What I want to do is combine and make it a single row where the type is Senior, the cashamount and Tenderamount are the same as well. This is my desired result: I'm getting my data from this table: Here's my query: SELECT a.DATE as `DATE`, a.employee as `EMPLOYEE`, a.TYPEID, a.NAME as `NAME`, (select (case when a.typeid = 1 then a.amount else NULL end)) as `CASHAMOUNT`, (select (case when a.typeid <> 1 then a.amount else NULL end)) as `TENDERAMOUNT`, (select gndtndr.IDENT from gndtndr where gndtndr.TYPE = 12 and `gndtndr`.`CHECK`= a.CHECK and gndtndr.DATE = a.DATE) as `ID`, from gndtndr a where STR_TO_DATE(a.DATE, '%m/%d/%Y') BETWEEN '20170901' AND '20170901' order by STR_TO_DATE(a.DATE, '%m/%d/%Y')
My MySQL is a bit rusty, but give this a try! SELECT a.Date, a.Employee, a.Name, a.ID, SUM(b.Amount) AS CashAmount, SUM(c.Amount) AS TenderAmount FROM (SELECT DISTINCT Date, Employee, Name, ID FROM gndtndr WHERE Type = 12) AS a LEFT JOIN gndtndr AS b ON a.ID = b.ID AND b.TypeID = 1 LEFT JOIN gndtdr AS c ON a.ID = c.ID and c.TypeID <> 1 GROUP BY a.Date, a.Employee, a.Name, a.ID
I've figured it out :) I just have to define the type conditions in my where clause where the type is 1(for cash). SELECT a.DATE as `DATE`, a.employee as `EMPLOYEE`, a.TYPEID, a.NAME as `NAME`, (select sum(gndtndr.amount) from gndtndr where gndtndr.typeid = 1 and gndtndr.`CHECK` = a.`CHECK` and gndtndr.DATE = a.DATE) as `CASHAMOUNT`, (select (case when a.typeid <> 1 then a.amount else NULL end)) as `TENDERAMOUNT`, (select gndtndr.IDENT from gndtndr where gndtndr.TYPE = 12 and `gndtndr`.`CHECK`= a.CHECK and gndtndr.DATE = a.DATE) as `ID` from gndtndr a where a.TYPEID <> 1 and STR_TO_DATE(a.DATE, '%m/%d/%Y') BETWEEN '20170901' AND '20170901' order by STR_TO_DATE(a.DATE, '%m/%d/%Y')
Converting rows records to columns in mySQL
I'm trying to convert row data to columns. Data will be extracted from different tables. I tried using PIVOTbut I'm not much successful. Lets consider column#1 as primary key in every table. CREATE TABLE Table_pivot_01 ([SSN ID] int, [Citizen_name] varchar(5), [Company] varchar(4)) ; INSERT INTO Table_pivot_01 ([SSN ID], [Citizen_name], [Company]) VALUES (12345, 'John', 'XYZ'), (12346, 'Tom', 'ABC'), (12347, 'Jerry', 'QWER'), (12348, 'Joe', 'PQR'), (12349, 'Josh', NULL) ; CREATE TABLE Table_pivot_02 ([Serial] int, [SSN_ID] int, [Family_details] varchar(9), [Family_members_name] varchar(10)) ; INSERT INTO Table_pivot_02 ([Serial], [SSN_ID], [Family_details], [Family_members_name]) VALUES (1010, 12345, 'Spouse', 'Mari'), (1011, 12345, 'Child - 1', 'John Jr. 1'), (1012, 12345, 'Child - 2', 'John Jr. 2'), (1013, 12346, 'Spouse', 'Ken'), (1014, 12347, 'Spouse', 'Suzen'), (1015, 12347, 'Child - 1', 'Jerry Jr.1'), (1016, 12347, 'Child - 2', 'Jerry Jr.2'), (1017, 12347, 'Child - 3', 'Jerry Jr.3'), (1018, 12348, 'Child - 1', 'Joe Jr.1'), (1019, 12348, 'Child - 2', 'Joe Jr.2'), (1020, 12349, 'Spouse', 'Zoe'), (1021, 12349, 'Child - 1', 'Josh Jr.1'), (1022, 12349, 'Child - 2', 'Josh Jr.2') ; CREATE TABLE Table_pivot_03 ([Row] int, [SSN_ID] int, [Address_type] varchar(8), [Address] varchar(22), [PhoneNumber_type] varchar(6), [PhoneNumber] varchar(18)) ; INSERT INTO Table_pivot_03 ([Row], [SSN_ID], [Address_type], [Address], [PhoneNumber_type], [PhoneNumber]) VALUES (121, 12345, 'Present', 'Address_John_Present', 'Home', 'John_Home_phone'), (122, 12345, 'Office', 'Address_John_Office', 'Office', 'John_Office_phone'), (123, 12345, 'Perement', 'Address_John_Perement', 'Fax', 'John_FAX_phone'), (124, 12346, 'Present', 'Address_Tom_Present', 'Home', 'Tom_Home_phone'), (125, 12346, 'Office', 'Address_Tom_Office', 'Office', 'Tom_Office_phone'), (126, 12347, 'Office', 'Address_Jerry_Office', 'Home', 'Jerry_Home_phone'), (127, 12347, 'Perement', 'Address_Jerry_Perement', 'Office', 'Jerry_Office_phone'), (128, 12348, 'Present', 'Address_Joe_Present', 'Home', 'Joe_Home_phone'), (129, 12348, 'Office', 'Address_Joe_Office', 'Office','Joe_Office_phone'), (130, 12348, 'Perement' , 'Address_Josh_Perement','','' ), (131, 12349, 'Present','Address_Josh_Present','Home','Josh_Home_phone'), (132, 12349, 'Perement', 'Address_Josh_Perement' , 'Fax' ,'Josh_FAX_phone'); Table schema : http://rextester.com/MSXK16689 The Expected Output is: How can I build the result in effective way?
MySQL Version You've stated that you have tried using PIVOT but MySQL doesn't have a PIVOT function. In MySQL you need to use an aggregate function along with a conditional logic statement like CASE...WHEN or something similar. You also have several tables and several different columns you need to pivot which complicates this a bit. It also seems that you have an unknown number of new columns that need to be created, which adds another layer of complexity. If you know all of the columns you want to be displayed in the final result, then you can easily type up a version of this query to be something like: select p1.`SSN_ID`, p1.Citizen_name, p1.Company, max(case when p2.Family_details = 'Spouse' then Family_members_name end) Spouse, max(case when p2.Family_details = 'Child - 1' then Family_members_name end) Child1, max(case when p2.Family_details = 'Child - 2' then Family_members_name end) Child2, max(case when p2.Family_details = 'Child - 3' then Family_members_name end) Child3, max(case when p2.Family_details = 'Child - 4' then Family_members_name end) Child4, max(case when p3.Address_type = 'Present' then p3.Address end) PresentAddress, max(case when p3.Address_type = 'Office' then p3.Address end) OfficeAddress, max(case when p3.Address_type = 'Perement' then p3.Address end) PermAddress, max(case when p3.PhoneNumber_type = 'Home' then p3.PhoneNumber end) HomePhone, max(case when p3.PhoneNumber_type = 'Office' then p3.PhoneNumber end) OfficePhone, max(case when p3.PhoneNumber_type = 'Fax' then p3.PhoneNumber end) FaxPhone from Table_pivot_01 p1 left join Table_pivot_02 p2 on p1.`SSN_ID` = p2.`SSN_ID` left join Table_pivot_03 p3 on p1.`SSN_ID` = p3.`SSN_ID` group by p1.`SSN_ID`, p1.Citizen_name, p1.Company; Basically you create a new column in a max(case... statement and it will display the value. As mentioned, this gets a bit more complicated if you have unknown values you want as columns. In MySQL you need to use a Prepared Statement so you can use dynamic SQL. Your code would looks sort of like this: SET #sql = NULL; SET #sql1 = NULL; SET #sql2 = NULL; SET #sql3 = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( ' max(case when p2.Family_details = ''', Family_details, ''' then Family_members_name end) AS `', Family_details, '`' ) ) INTO #sql1 FROM Table_pivot_02; SELECT GROUP_CONCAT(DISTINCT CONCAT( ' max(case when p3.Address_type = ''', Address_type, ''' then Address end) AS `', Address_type, '`' ) ) INTO #sql2 FROM Table_pivot_03; SELECT GROUP_CONCAT(DISTINCT CONCAT( ' max(case when p3.PhoneNumber_type = ''', PhoneNumber_type, ''' then PhoneNumber end) AS `', PhoneNumber_type, '`' ) ) INTO #sql3 FROM Table_pivot_03 where PhoneNumber_type <> ''; SET #sql = CONCAT('SELECT p1.`SSN_ID`, p1.Citizen_name, p1.Company, ', #sql1, ',', #sql2, ',', #sql3, ' from Table_pivot_01 p1 left join Table_pivot_02 p2 on p1.`SSN_ID` = p2.`SSN_ID` left join Table_pivot_03 p3 on p1.`SSN_ID` = p3.`SSN_ID` group by p1.`SSN_ID`, p1.Citizen_name, p1.Company'); PREPARE stmt FROM #sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; In this you are creating a long string of the max(case... statements that get concatenated together to then be executed by the database engine. There may be easier ways to get the result you want, but this does work. I've created a demo on rextester to show the code. Both of these produce a result: +-------+--------+--------------+---------+--------+------------+------------+------------+----------------------+----------------------+------------------------+------------------+--------------------+----------------+ | Row | SSN_ID | Citizen_name | Company | Spouse | Child - 1 | Child - 2 | Child - 3 | Present | Office | Perement | Home | Office | Fax | +-------+--------+--------------+---------+--------+------------+------------+------------+----------------------+----------------------+------------------------+------------------+--------------------+----------------+ | 1 | 12345 | John | XYZ | Mari | John Jr. 1 | John Jr. 2 | NULL | Address_John_Present | Address_John_Office | Address_John_Perement | John_Home_phone | John_Office_phone | John_FAX_phone | | 2 | 12346 | Tom | ABC | Ken | NULL | NULL | NULL | Address_Tom_Present | Address_Tom_Office | NULL | Tom_Home_phone | Tom_Office_phone | NULL | | 3 | 12347 | Jerry | QWER | Suzen | Jerry Jr.1 | Jerry Jr.2 | Jerry Jr.3 | NULL | Address_Jerry_Office | Address_Jerry_Perement | Jerry_Home_phone | Jerry_Office_phone | NULL | | 4 | 12348 | Joe | PQR | NULL | Joe Jr.1 | Joe Jr.2 | NULL | Address_Joe_Present | Address_Joe_Office | Address_Josh_Perement | Joe_Home_phone | Joe_Office_phone | NULL | | 5 | 12349 | Josh | NULL | Zoe | Josh Jr.1 | Josh Jr.2 | NULL | Address_Josh_Present | NULL | Address_Josh_Perement | Josh_Home_phone | NULL | Josh_FAX_phone | +-------+--------+--------------+---------+--------+------------+------------+------------+----------------------+----------------------+------------------------+------------------+--------------------+----------------+ Based on your comment that you might have more than one phone number type per person, you'll need to create a row number for each group of phone types. Unfortunately, again MySQL doesn't have windowing function so you'll need to use user defined variables to get the final result. When you query for PhoneNumber_type you'll need to use something like: select * from ( select SSN_ID, PhoneNumber_type, PhoneNumber, #num:= case when #group = SSN_ID and #type = PhoneNumber_type then #num +1 else if(#group := SSN_ID, 1, 1) end rn, #group:= SSN_ID, #type:=PhoneNumber_type from Table_pivot_03 t CROSS JOIN (select #num:=0, #group:=null, #type:=null) c where t.PhoneNumber_type <> '' order by SSN_ID, PhoneNumber_type ) as x; This creates a row number value for each user and phone type. You'd then integrate this into the dynamic SQL code: SET #sql = NULL; SET #sql1 = NULL; SET #sql2 = NULL; SET #sql3 = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT( ' max(case when p2.Family_details = ''', Family_details, ''' then Family_members_name end) AS `', Family_details, '`' ) ) INTO #sql1 FROM Table_pivot_02; SELECT GROUP_CONCAT(DISTINCT CONCAT( ' max(case when p3.Address_type = ''', Address_type, ''' then Address end) AS `', Address_type, '`' ) ) INTO #sql2 FROM Table_pivot_03; SELECT GROUP_CONCAT(DISTINCT CONCAT( ' max(case when p.PhoneNumber_type = ''', PhoneNumber_type, ''' and rn = ', rn, ' then p.PhoneNumber end) AS `', PhoneNumber_type, rn, '`' ) ) INTO #sql3 FROM ( select SSN_ID, PhoneNumber_type, PhoneNumber, #num:= case when #group = SSN_ID and #type = PhoneNumber_type then #num +1 else if(#group := SSN_ID, 1, 1) end rn, #group:= SSN_ID, #type:=PhoneNumber_type from Table_pivot_03 t CROSS JOIN (select #num:=0, #group:=null, #type:=null) c where t.PhoneNumber_type <> '' order by SSN_ID, PhoneNumber_type ) as x; SET #sql = CONCAT('SELECT p1.`SSN_ID`, p1.Citizen_name, p1.Company, ', #sql1, ',', #sql2, ',', #sql3, ' from Table_pivot_01 p1 left join Table_pivot_02 p2 on p1.`SSN_ID` = p2.`SSN_ID` left join Table_pivot_03 p3 on p1.SSN_ID = p3.SSN_Id left join ( select SSN_ID, PhoneNumber_type, PhoneNumber, #num:= case when #group = SSN_ID and #type = PhoneNumber_type then #num +1 else if(#group := SSN_ID, 1, 1) end rn, #group:= SSN_ID, #type:=PhoneNumber_type from Table_pivot_03 t CROSS JOIN (select #num:=0, #group:=null, #type:=null) c where t.PhoneNumber_type <> '''' order by SSN_ID, PhoneNumber_type ) as p on p1.SSN_ID = p.SSN_Id group by p1.`SSN_ID`, p1.Citizen_name, p1.Company'); #select #sql; PREPARE stmt FROM #sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; See another demo. SQL Server Version Since you've now said that you need a SQL Server version here is that version. SQL Server has a few features that make doing this significantly easier including a PIVOT function, UNPIVOT function, and windowing functions like row_number. Here's a static version of the query with just a few columns pivoted: select SSN_ID, Citizen_name, Company, Spouse, [Child - 1], [Child - 2], [Child - 3], [Child - 4] from ( select SSN_ID, Citizen_name, Company, col, value from ( select p1.SSN_ID, p1.Citizen_name, p1.Company, p2.Family_details, p2.Family_members_name, p3.Address_type, p3.Address, PhoneNumber_type = p.PhoneNumber_type + cast(p.rn as varchar(10)), p.PhoneNumber from Table_pivot_01 p1 left join Table_pivot_02 p2 on p1.SSN_ID = p2.SSN_ID left join Table_pivot_03 p3 on p1.SSN_ID = p3.SSN_ID left join ( select SSN_ID, PhoneNumber_type, PhoneNumber, rn = row_number() over(partition by SSN_ID, PhoneNumber_type order by SSN_ID, PhoneNumber_type) from Table_pivot_03 where PhoneNumber_type <> '' ) p on p1.SSN_ID = p.SSN_ID ) d cross apply ( select 'Family_details', Family_details, Family_members_name union all select 'Address_type', Address_type, Address union all select 'PhoneNumber_type', PhoneNumber_type, PhoneNumber ) c(orig, col, value) ) src pivot ( max(value) for col in (Spouse, [Child - 1], [Child - 2], [Child - 3], [Child - 4]) ) piv Then if you need a dynamic sql version the code would be like: DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX) select #cols = STUFF((SELECT ',' + QUOTENAME(Col) from ( select col, ord from ( select p1.SSN_ID, p1.Citizen_name, p1.Company, p2.Family_details, p2.Family_members_name, p3.Address_type, p3.Address, PhoneNumber_type = p.PhoneNumber_type + cast(p.rn as varchar(10)), p.PhoneNumber from Table_pivot_01 p1 left join Table_pivot_02 p2 on p1.SSN_ID = p2.SSN_ID left join Table_pivot_03 p3 on p1.SSN_ID = p3.SSN_ID left join ( select SSN_ID, PhoneNumber_type, PhoneNumber, rn = row_number() over(partition by SSN_ID, PhoneNumber_type order by SSN_ID, PhoneNumber_type) from Table_pivot_03 where PhoneNumber_type <> '' ) p on p1.SSN_ID = p.SSN_ID ) d cross apply ( select 'Family_details', Family_details, Family_members_name, 1 union all select 'Address_type', Address_type, Address, 2 union all select 'PhoneNumber_type', PhoneNumber_type, PhoneNumber, 3 ) c(orig, col, value, ord) ) d group by col, ord order by ord, col FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,''); set #query = N'SELECT ' + #cols + N' from ( select SSN_ID, Citizen_name, Company, col, value from ( select p1.SSN_ID, p1.Citizen_name, p1.Company, p2.Family_details, p2.Family_members_name, p3.Address_type, p3.Address, PhoneNumber_type = p.PhoneNumber_type + cast(p.rn as varchar(10)), p.PhoneNumber from Table_pivot_01 p1 left join Table_pivot_02 p2 on p1.SSN_ID = p2.SSN_ID left join Table_pivot_03 p3 on p1.SSN_ID = p3.SSN_ID left join ( select SSN_ID, PhoneNumber_type, PhoneNumber, rn = row_number() over(partition by SSN_ID, PhoneNumber_type order by SSN_ID, PhoneNumber_type) from Table_pivot_03 where PhoneNumber_type <> '''' ) p on p1.SSN_ID = p.SSN_ID ) d cross apply ( select ''Family_details'', Family_details, Family_members_name union all select ''Address_type'', Address_type, Address union all select ''PhoneNumber_type'', PhoneNumber_type, PhoneNumber ) c(orig, col, value) ) src pivot ( max(value) for col in (' + #cols + N') ) p ' exec sp_executesql #query; Here is another demo.
Unknown column in subquery - mysql
I am very close to completing this difficult query. It's quite long, so hopefully not too overwhelming. But in my case statment in the select block I am referencing a union from my where statement. It is giving me "MySQL Database Error: Unknown column 'U.EmpID' in 'where clause'". Any help would be much appreciated. And here is the query: SELECT U.EmpID, CASE WHEN ((SELECT COUNT(*) FROM (SELECT * FROM timeclock_copy tp WHERE PunchEvent = 'breakin' AND DATE(tp.PunchDateTime) = '2013-11-12' AND tp.EmpID = U.EmpID) AS s) > 1) AND ((SELECT COUNT(*) FROM (SELECT * FROM timeclock_copy tp WHERE PunchEvent = 'breakout' AND DATE(tp.PunchDateTime) = '2013-11-12' AND tp.EmpID = U.EmpID) AS s) > 1) THEN "MULTIPLE BREAKS" ELSE "ONE BREAK" END AS Lunch FROM ((SELECT `enter`.EmpID, `enter`.PunchDateTime AS `time`, DATE_FORMAT(`enter`.PunchDateTime, '%m-%d-%Y') AS 'Punch Date', TIMESTAMPDIFF(SECOND, `enter`.PunchDateTime, '2003-05-01 00:00:00') AS `delta` FROM timeclock_copy AS `enter` WHERE `enter`.`In-Out` = 1) UNION (SELECT `leave`.EmpID, `leave`.PunchDateTime AS `time`, DATE_FORMAT(`leave`.PunchDateTime, '%m-%d-%Y') AS 'Punch Date', -TIMESTAMPDIFF(SECOND, `leave`.PunchDateTime, '2003-05-01 00:00:00') AS `delta` FROM timeclock_copy AS `leave` WHERE `leave`.`In-Out` = 0)) AS U LEFT JOIN testclb.prempl pe ON u.EmpID = pe.prempl WHERE DATE(U.`time`) >= '2013-11-12' AND DATE(U.`time`) < '2013-11-13' GROUP BY date(U.`time`), EmpID ORDER BY U.EmpID, U.`time` ASC
Subqueries in FROM clauses cannot be correlated with the outer statement. I think this is why you are getting the Unknown column 'U.EmpID' in 'where clause'" error.