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.