I have the following table:
ID_TableDetails
FK_TableMaster
StartDate
EndDate
StartTime
EndTime
1
1
2021-05-24
2021-05-24
10:00
11:00
2
1
2021-05-25
2021-05-25
10:00
11:00
3
1
2021-05-26
2021-05-26
11:00
12:00
4
2
2021-05-27
2021-05-27
11:00
12:00
5
2
2021-05-28
2021-05-28
11:00
12:00
6
2
2021-05-29
2021-05-29
11:00
12:00
I want to select values from the above table in the following manner
1stID
2ndID
3rdID
1stStartDte
1stStartTimeEndTime
2ndStartDte
2ndStartTimeEndTime
3rdStartDte
3rdStartTimeEndTime
1
2
3
2021-05-24
10:00 TO 11:00
2021-05-25
10:00 TO 11:00
2021-05-26
11:00 TO 12:00
4
5
6
2021-05-24
10:00 TO 11:00
2021-05-25
10:00 TO 11:00
2021-05-26
11:00 TO 12:00
There will always be three entries for FK_TableMaster and I want to select is as one row.
This is what I have tried
SELECT
ID_TableDetils, Description, Startate, EndDate, StartTime, EndTime
FROM
TableDetils AS TD
JOIN
TableMaster AS TM ON TD.ID_TableDetils = TM.FK_TableMaster
This will return multiple rows for FK_TableMaster - I don't know how to select it as a single row any help would be appreciated.
UPDATE based on :Group by column and multiple Rows into One Row multiple columns
WITH RNs AS
(
SELECT ID_TableDetails,
FK_TableMaster,
StartDate,
EndDate,
ROW_NUMBER() OVER (PARTITION BY ID_PtaEventScheduleDetails, FK_PtaEventSchedule ORDER BY (SELECT NULL)) AS RN --ORDER BY should be your ID/always ascending column
FROM dbo.TableDetails
WHERE Cancelled = 0 AND FK_TableMaster = 1
)
SELECT
ID_TableDetails,
FK_TableMaster,
MAX(CASE RN WHEN 1 THEN StartDate END) AS Result1,
MAX(CASE RN WHEN 2 THEN StartDate END) AS Result2,
MAX(CASE RN WHEN 3 THEN StartDate END) AS Result3,
MAX(CASE RN WHEN 1 THEN EndDate END) AS Result4,
MAX(CASE RN WHEN 1 THEN EndDate END) AS Result5,
MAX(CASE RN WHEN 1 THEN EndDate END) AS Result6
FROM
RNs R
GROUP BY
ID_TableDetails, FK_TableMaster
This is a duplicate of the proposed dupe candidate Group by column and multiple Rows into One Row multiple columns but to post the same answer again, replacing the columns from my other answer with the OP's:
WITH RNs AS(
SELECT ID_TableDetails,
FK_TableMaster,
StartDate,
EndDate,
StartTime,
EndTime,
ROW_NUMBER() OVER (PARTITION BY FK_TableMaster ORDER BY ID_TableDetails) AS RN
FROM dbo.Result)
SELECT MAX(CASE RN WHEN 1 THEN ID_TableDetails END) AS ID1,
MAX(CASE RN WHEN 2 THEN ID_TableDetails END) AS ID2,
MAX(CASE RN WHEN 3 THEN ID_TableDetails END) AS ID3,
MAX(CASE RN WHEN 1 THEN StartDate END) AS StartDate1,
MAX(CASE RN WHEN 1 THEN StartTime END) AS StartTime1,
MAX(CASE RN WHEN 1 THEN EndTime END) AS EndTime1,
... --You get the idea
MAX(CASE RN WHEN 3 THEN EndTime END) AS EndTime3
FROM RNs R
GROUP BY FK_TableMaster;
Related
I have a table that specifies exactly what date and time each employee was in a particular office.I want to know on what date and time each employee arrived at work and on what date and time he left work. I also want to know how many times he has been at work in each time process.
EmployeeTable looks like this:
id
EmployeeID
DateP
TimeP
1
11111
1397/01/02
01:30
2
11111
1398/05/09
05:30
3
11111
1398/06/07
05:10
4
22222
1398/08/09
06:12
5
22222
1399/02/01
07:15
6
11111
1399/07/02
08:51
7
11111
1399/08/06
12:20
8
33333
1399/09/04
20:01
9
33333
1399/12/08
22:05
10
33333
1400/01/01
23:11
11
33333
1400/02/05
14:10
12
22222
1400/04/05
16:25
I want exactly select Min and Max date and time for each Employee when present in a office and how many times he/she has been present at work in each stage.:
id
EmployeeID
MinDateP
TimeMinDateP
MaxDateP
TimeMaxDateP
Count
1
11111
1397/01/02
01:30
1398/06/07
05:10
3
2
22222
1398/08/09
06:12
1399/02/01
07:15
2
3
11111
1399/07/02
08:51
1399/08/06
12:20
2
4
33333
1399/09/04
20:01
1400/02/05
14:10
4
5
22222
1400/04/05
16:25
1400/04/05
16:25
1
This is the SQL code that indicates exactly when each employee arrived at work and when he or she left work :
WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY DateP, TimeP) rn1,
ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY DateP, TimeP) rn2
FROM
EmployeeTable
),
cte2 AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY EmployeeID, rn1 - rn2
ORDER BY DateP, TimeP) rn_first,
ROW_NUMBER() OVER (PARTITION BY EmployeeID, rn1 - rn2
ORDER BY DateP DESC, TimeP DESC) rn_last
FROM
cte
)
SELECT
EmployeeID,
MAX(CASE WHEN rn_first = 1 THEN DateP END) AS MinDateP,
MAX(CASE WHEN rn_first = 1 THEN TimeP END) AS TimeMinDateP,
MAX(CASE WHEN rn_last = 1 THEN DateP END) AS MaxDateP,
MAX(CASE WHEN rn_last = 1 THEN TimeP END ) AS TimeMaxDateP
FROM
cte2
GROUP BY
EmployeeID,
rn1 - rn2
ORDER BY
MIN(DateP), MIN(TimeP);
But I want to know how many times each employee has been at work at any given time (Count column)
Can anybody help me?
If I understand correctly, you just want to know the number of records in each employee island. In that case, just select COUNT(*) in your final query:
SELECT
EmployeeID,
MAX(CASE WHEN rn_first = 1 THEN DateP END) AS MinDateP,
MAX(CASE WHEN rn_first = 1 THEN TimeP END) AS TimeMinDateP,
MAX(CASE WHEN rn_last = 1 THEN DateP END) AS MaxDateP,
MAX(CASE WHEN rn_last = 1 THEN TimeP END) AS TimeMaxDateP,
COUNT(*) AS count
FROM cte2
GROUP BY
EmployeeID,
rn1 - rn2
ORDER BY
MIN(DateP),
MIN(TimeP);
How can I add row and column grand totals in the table below?
I want to get total and grand total by months.
However, I couldn't do that.
SELECT *
FROM(
SELECT
YEAR(DueDate) [Year],
CASE MONTH(DueDate)
WHEN 1 THEN 'January'
WHEN 2 THEN 'February'
WHEN 3 THEN 'March'
WHEN 4 THEN 'April'
WHEN 5 THEN 'May'
WHEN 6 THEN 'June'
WHEN 7 THEN 'July'
WHEN 8 THEN 'August'
WHEN 9 THEN 'September'
WHEN 10 THEN 'October'
WHEN 11 THEN 'November'
WHEN 12 THEN 'December'
END as [Month],
ProductID,
OrderQty
FROM Production.WorkOrder
) WorkOrders
PIVOT
(
SUM(OrderQty)
FOR [Month] IN (
[January],[February],[March],[April],
[May],[June],[July],[August],
[September],[October],[November],[December]
)
) AS PivotTable
ORDER BY [Year], ProductID
Stuff like this is far easier using a conditional aggregate over the restrictive PIVOT operator.
Without sample data, nor expected results, this isn't tested, but you should be able to achieve what you're after with something like this:
SELECT CASE WHEN GROUPING(DATEPART(YEAR,DueDate)) = 0 THEN
CAST(DATEPART(YEAR,DueDate) AS varchar(50))
ELSE 'GrandTotal' END AS [Year],
SUM(CASE DATEPART(MONTH,DueDate) WHEN 1 THEN OrderQty END) AS January, --Don't use single quotes for alaises,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 2 THEN OrderQty END) AS Feburary, --it can be very confusing to read.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 3 THEN OrderQty END) AS March, --Single quotes are for literal strings.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 4 THEN OrderQty END) AS April, --Using ' for alias only work in the SELECT too,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 5 THEN OrderQty END) AS May, --something like ORDER BY 'January' would not
SUM(CASE DATEPART(MONTH,DueDate) WHEN 6 THEN OrderQty END) AS June, --order by data by the column aliases as 'January'.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 7 THEN OrderQty END) AS July,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 8 THEN OrderQty END) AS August,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 9 THEN OrderQty END) AS September,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 10 THEN OrderQty END) AS October,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 11 THEN OrderQty END) AS November,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 12 THEN OrderQty END) AS December,
SUM(OrderQty) AS GrandTotal,
ProductID
FROM Production.WorkOrder
GROUP BY GROUPING SETS(
(DATEPART(YEAR, DueDate), ProductID),
(DATEPART(YEAR, DueDate)),
()
);
I need query which fetch records from two tables but column name should be based on records in second table.
Details are below
My first table
Emp Table
emp_id emp_name
1 Abc
2 XYZ
3 PQR
My second table
Salary Table
id emp_id month salary
1 1 1 4000
2 1 2 3000
3 2 1 5000
4 2 2 4500
I need output like,
emp_id emp_name jan feb
1 Abc 4000 3000
2 XYZ 5000 4500
I am able to achieve this by using left join but for every month I need to add it in query like,
select e.emp_id,e.emp_name,j.month as Jan,f.month as Feb from emp e
Left Join salary j on e.emp_id=j.emp_id and j.month=1
Left Join salary f on e.emp_id=f.emp_id and f.month=2
Above work for me But which is not feasible. I have master table for month also.
Month Table
id Name
1 Jan
2 Feb
3 March
5 April
I want fetch record for for specific month currently for (Jan & feb).
Please help me achieve this faster way.
Using conditional aggregation:
SELECT
e.emp_id,
e.emp_name,
[Jan] = MAX(CASE WHEN s.[month] = 1 THEN s.salary END),
[Feb] = MAX(CASE WHEN s.[month] = 2 THEN s.salary END),
[Mar] = MAX(CASE WHEN s.[month] = 3 THEN s.salary END),
[Apr] = MAX(CASE WHEN s.[month] = 4 THEN s.salary END),
[May] = MAX(CASE WHEN s.[month] = 5 THEN s.salary END),
[Jun] = MAX(CASE WHEN s.[month] = 6 THEN s.salary END),
[Jul] = MAX(CASE WHEN s.[month] = 7 THEN s.salary END),
[Aug] = MAX(CASE WHEN s.[month] = 8 THEN s.salary END),
[Sep] = MAX(CASE WHEN s.[month] = 9 THEN s.salary END),
[Oct] = MAX(CASE WHEN s.[month] = 10 THEN s.salary END),
[Nov] = MAX(CASE WHEN s.[month] = 11 THEN s.salary END),
[Dec] = MAX(CASE WHEN s.[month] = 12 THEN s.salary END)
FROM Emp e
LEFT JOIN Salary s
ON s.emp_id = e.emp_id
GROUP BY
e.emp_id, e.emp_name
ONLINE DEMO
I have a table with following column and I would like to update it as following.
The Logic is the start date take the date will be updated if overlap with following rules: take the earliest start date and enddate of the latest row with overlapping date based on member id. And the status of the remaining overlap column will be updated to 2. Hope someone could help.
ID MemberID StartDate EndDate Status
1 2 2015-01-01 2015-02-28 1
2 2 2015-02-01 2015-02-03 1
3 2 2015-02-01 2015-03-01 1
4 1 2015-02-01 2015-02-28 1
5 3 2015-02-01 2015-02-28 1
6 2 2015-05-01 2015-05-20 1
I would like to update to
ID MemberID StartDate EndDate Status
1 2 2015-01-01 2015-03-01 1
2 2 2015-01-01 2015-03-01 2
3 2 2015-01-01 2015-03-01 2
4 1 2015-02-01 2015-02-28 1
5 3 2015-02-01 2015-02-28 1
6 2 2015-05-01 2015-05-20 1
I think this should do it :
update a set
a.startdate =
(select min(startdate) from #table where memberID = a.memberID),
a.enddate =
(select max(enddate) from #table where memberID = a.memberID),
a.status =
case when a.id =
(select min(id) from #table where memberID = a.memberID)
then status else 2
end
from #table a
Try this,
---- Creating CTE for finding overlapped dates
;WITH CTE AS (
SELECT A.ID,
B.ID AS MAPPED_ID,
A.MEMBERID,
B.STARTDATE,
B.ENDDATE,
B.STATUS
FROM #YOUR_TABLE A
JOIN #YOUR_TABLE B ON B.STARTDATE <= A.ENDDATE-- Condition for finding the overlapped dates
AND B.ENDDATE >= A.STARTDATE
AND A.MEMBERID = B.MEMBERID)-- end here
UPDATE T
SET T.STARTDATE = A.STARTDATE,
T.ENDDATE = A.ENDDATE,
T.STATUS = A.STATUS
FROM #YOUR_TABLE T
JOIN (SELECT ID,
MEMBERID,
STARTDATE,
ENDDATE,
STATUS=CASE
WHEN RN > 1 THEN 2
ELSE 1
END
FROM (SELECT T.ID,
T.MEMBERID,
CS1.STARTDATE,
CS2.ENDDATE,
ROW_NUMBER() -- ROWNUMBER FOR FINDING THE STATUS
OVER(
PARTITION BY T.MEMBERID, CS1.STARTDATE, CS2.ENDDATE
ORDER BY T.ID) AS RN
FROM #YOUR_TABLE T
CROSS APPLY (SELECT CAST(MIN(STARTDATE)AS DATETIME) AS STARTDATE --- FINDING MIN(STARTDATE) FOR THE OVERLAPPED GROUP
FROM CTE A
WHERE A.ID = T.ID) CS1
CROSS APPLY (SELECT ENDDATE -- FINDING LAST ENDDATE FOR THE OVERLAPPED GROUP (IE RN=1)
FROM (SELECT ENDDATE,--- ROW_NUMBER FOR THE OVERLAPPED GROUPS
ROW_NUMBER()
OVER(
ORDER BY B.MAPPED_ID DESC) AS RN
FROM CTE B
WHERE B.ID = T.ID)A
WHERE A.RN = 1)CS2)A)A ON A.ID = T.ID
SELECT *
FROM #YOUR_TABLE
Table "tblCustomer":
Customer_id
created
field1
field2
cardno
1014
2010-05-25 12:51:59.547
Cell Phone
abc#lmn.com
1234567890
1015
2010-08-15 12:51:59.547
Email
abc#xyz.com
2345678891
Table "tbl_TransactionDishout":
Trnx_id
offerNo
TerminalID
Created
VirtualCard
1
1014
170924690436418
2010-05-25 12:51:59.547
1234567890
Expected Output:
Enrolled
Enrolled as Email
Enrolled as Text
Deals Redeemed
<First Date>
7
5
2
6
<Next Date>
9
3
6
14
I have two different queries which I need to combine into one.
First One:
SELECT CAST(FLOOR(CAST(t.created AS FLOAT )) AS Datetime) created,
COUNT(field1) Enrolled,
COUNT(CASE field1 WHEN 'E-mail' THEN 1 END) Enrolled_as_Email,
COUNT(CASE field1 WHEN 'Cell Phone' THEN 1 END) Enrolled_as_Cell
FROM tblCustomer as t
GROUP BY t.created
ORDER BY t.created DESC
Which Displays:
create
Enrolled
Enrolled_as_Email
Enrolled_as_Cell
2012-03-01 00:00:00.000
3
1
2
2012-02-29 00:00:00.000
1
0
1
Second One:
SELECT CAST(FLOOR(CAST(t.created AS FLOAT)) AS Datetime) created,
COUNT(*) [Deals_Redeemed]
FROM tbl_TransactionDishout t
LEFT JOIN tblCustomer c
ON t.VirtualCard = c.cardno
GROUP BY CAST(FLOOR(CAST(t.created AS FLOAT )) as Datetime)
ORDER BY t.created desc
Which Displays:
create
Deals_Redeemed
2012-03-02 00:00:00.000
1
2012-03-01 00:00:00.000
6
2012-02-28 00:00:00.000
1
2012-02-27 00:00:00.000
2
Now I want a record which contain date from both and should be combined into one.
But It's giving me the result of the date contained only in tblCustomer table..
How to get "Deals_redeemed"?
Note: relation between tbl_transaction and tblCustomer is having same cardno.
SELECT
CAST(t1.created AS DATE) created,
COUNT(t1.field1) Enrolled,
COUNT(CASE t1.field1 WHEN 'E-mail' THEN 1 END) Enrolled_as_Email,
COUNT(CASE t1.field1 WHEN 'Cell Phone' THEN 1 END) Enrolled_as_Cell,
COUNT(t2.created) Deals_Redeemed
FROM tblCustomer AS t1
LEFT JOIN tbl_TransactionDishout t2
ON t1.cardno = t2.VirtualCard
GROUP BY CAST(t1.created AS DATE)
ORDER BY CAST(t1.created AS DATE) DESC
Edit: Changed condition to cardno, and changed from FULL JOIN to LEFT JOIN.
You could Pivot():
select [create]
, sum([Email]+[Cell Phone]) as [Enrolled]
, max([Email]) as [Enrolled as Email]
, max([Cell Phone]) as [Enrolled as Cell Phone]
, max([Deal Redeemed]) as [Deals Redeemed]
from (
select [create]=created
, create1=created
, field1
from tblCustomer
union all
select [create]=created
, create1=created
, field1='Deal Redeemed'
from tbl_TransactionDishout
) p
pivot (
count(create1)
for field1 in ([Cell Phone],[Email],[Deal Redeemed])
) pv
group by [create]
order by [create]