SQL Server : duplicate counts - sql

I have the following. But in the final result some of the employee ID's are counted twice. My goal is to only count distinct employeeID for the [UniqueEmployees] column... Can someone please help me?
This is the code here:
IF OBJECT_ID(N'tempdb..#GG') IS NOT NULL
DROP TABLE #GG
SELECT DISTINCT
[month], vv.Hiremonth,
LoanNumber, vv.EmployeeId,
agentname,
vv.YearsOfService, vv.MonthsofService,
vv.TenureGrouping, vv.TenureMonthGrouping,
manager,
SUM([Call Counts]) as Calls,
SUM(opportunities) as Opportunities,
SUM([Discussed w/Customer]) as [Discussed w/Customer],
SUM(DidNotDiscuss) as [DidNotDiscuss],
SUM(CustomerInterested) as CustomerInterested,
(SELECT COUNT(DISTINCT MGR.EmployeeId)
FROM #MANAGERS MGR
WHERE --EmployeeId = EmployeeId
--and
CAST(CONVERT(datetime, RIGHT(MGR.HireMonth, 4) + LEFT(MGR.HireMonth, 2) + '01') as DATE) <= CAST(CONVERT(datetime, right([Month], 4) + left([Month], 2) + '01') as DATE)
--and MonthsOfService = MonthsOfService
--and YearsOfService = YearsOfService
) as UniqueEmployees
INTO
#GG
FROM
#FINALtemp2b VV
--left join
--(select distinct Employeeid
--from #FINALtemp2b) CC
--on CC.EmployeeId = VV.EmployeeId
GROUP BY
[month], vv.Hiremonth, LoanNumber, vv.EmployeeId,
agentname, vv.YearsOfService, vv.MonthsofService,
vv.TenureGrouping, vv.TenureMonthGrouping, manager
ORDER BY
[month]

Try removing the first 'distinct' and the excess 'select'.
IF OBJECT_ID(N'tempdb..#GG') is not null Drop Table #GG
select *
into #GG
from (
select
[month],
vv.Hiremonth,
LoanNumber,
vv.EmployeeId,
agentname,
vv.YearsOfService,
vv.MonthsofService,
vv.TenureGrouping,
vv.TenureMonthGrouping,
manager,
SUM([Call Counts]) as Calls,
sum(opportunities) as Opportunities,
sum([Discussed w/Customer]) as [Discussed w/Customer],
sum(DidNotDiscuss) as [DidNotDiscuss],
sum(CustomerInterested) as CustomerInterested,
count(distinct (MGR.EmployeeId))
from #MANAGERS MGR
where cast(convert(datetime,right(MGR.HireMonth,4) + left(MGR.HireMonth,2) + '01') as DATE) <= cast(convert(datetime,right([Month],4) + left([Month],2) + '01') as DATE)
group by
[month],
vv.Hiremonth,
LoanNumber,
vv.EmployeeId,
agentname,
vv.YearsOfService,
vv.MonthsofService,
vv.TenureGrouping,
vv.TenureMonthGrouping,
manager
) as UniqueEmployees

Related

Multi Day Values

I am having some troubles with my query. I am trying to get the total import rate for the current day, while also matching up the previous day with the correlating hour.
Example: 1AM (Current Day) = 20
1AM(Yesterday) = 25.
As of right now the columns Current and Yesterday are showing identical values.
SELECT
z.[import Hour],
COUNT(z.orderno) as CurrentDate,
COUNT(od.orderno) as Yesterday
FROM (
(select datepart(hh, recvtime) as [import Hour],
orderno
from mck_hvs.orderheader with (nolock)
where convert(date, recvtime) = convert(date, getdate())
and orderno not like '%ST'
UNION
select datepart(hh, recvtime) as [import Hour],
orderno from mck_hvs.oldorderheader with (nolock)
where convert(date, recvtime) = convert(date, getdate())
and orderno not like '%ST' ) as z
Join
(
select datepart(hh, od.recvtime) as [import Hour],
od.orderno from mck_hvs.oldorderheader od with (nolock)
where convert(date, od.recvtime) = convert(date, getdate()-1)
and od.orderno not like '%ST' ) as OD
ON z.[import Hour] = od.[import Hour] )
group by z.[import Hour]
If you use following data:
DECLARE #Orders AS TABLE(OrderNo INT,OrderTaken datetime)
INSERT INTO #Orders VALUES(123,'2017-07-24 12:20:24')
INSERT INTO #Orders VALUES(124,'2017-07-24 12:30:24')
INSERT INTO #Orders VALUES(125,'2017-07-24 13:40:24')
INSERT INTO #Orders VALUES(126,'2017-07-24 13:50:24')
INSERT INTO #Orders VALUES(227,'2017-07-25 12:20:24')
INSERT INTO #Orders VALUES(228,'2017-07-25 12:30:24')
INSERT INTO #Orders VALUES(229,'2017-07-25 13:40:24')
INSERT INTO #Orders VALUES(220,'2017-07-25 13:50:24')
with output:
The following SQL:
DECLARE #Date DATETIME='2017-07-25'
;WITH today AS(
SELECT Cast(OrderTaken As Date) oDate,
CASE WHEN DATEPART(hh,OrderTaken) > 12 THEN CONVERT(VARCHAR(2),DATEPART(hh,OrderTaken)-12) + ' PM' WHEN DATEPART(hh,OrderTaken) = 12 THEN CONVERT(VARCHAR(2),DATEPART(hh,OrderTaken)) + ' PM' WHEN DATEPART(hh,OrderTaken) < 12 THEN CONVERT(VARCHAR(2),DATEPART(hh,OrderTaken)) + ' AM' END As oHour,
Count(OrderNo) OrderCountToday FROM #Orders
WHERE CAST(OrderTaken AS DATE)=CAST(#Date AS DATE)
GROUP BY Cast(OrderTaken As Date),DATEPart(Hour,OrderTaken)
)
,yesterday AS(
SELECT Cast(OrderTaken As Date) oDate,
CASE WHEN DATEPART(hh,OrderTaken) > 12 THEN CONVERT(VARCHAR(2),DATEPART(hh,OrderTaken)-12) + ' PM' WHEN DATEPART(hh,OrderTaken) = 12 THEN CONVERT(VARCHAR(2),DATEPART(hh,OrderTaken)) + ' PM' WHEN DATEPART(hh,OrderTaken) < 12 THEN CONVERT(VARCHAR(2),DATEPART(hh,OrderTaken)) + ' AM' END As oHour,
Count(OrderNo) OrderCountYesterday
FROM #Orders
WHERE CAST(OrderTaken AS DATE)=CAST(#Date-1 AS DATE)
GROUP BY Cast(OrderTaken As Date),DATEPart(Hour,OrderTaken)
)
SELECT t.oDate Today,t.oHour Hour,t.OrderCountToday,y.OrderCountYesterday FROM today t join yesterday y ON t.oHour=y.oHour and t.oDate=dateadd(day,1,y.oDate)
will result as:
p.s.: You can summarize this SQL a lot if you don't want to use AM/PM thing in the hour. Even the logic for AM/PM can be summarized further but that will show 12 PM as 0 PM.
Hope this help.
I've included a bit of code up front just to generate some test data. You probably won't need it, but others might.
USE sandbox
GO
--------------------------------------------------------------------------------------------
--Recreate the OP's environment in my sandpit
DROP TABLE IF EXISTS mck_hvs.orderheader --2016 syntax
create table mck_hvs.orderheader(
recvtime datetime NOT NULL
,orderno varchar(20) NOT NULL
)
;
ALTER TABLE mck_hvs.orderheader
ADD CONSTRAINT PK_mck_hvs_orderheader_orderno PRIMARY KEY CLUSTERED (orderno)
;
GO
--------------------------------------------------------------------------------------------
DROP TABLE IF EXISTS mck_hvs.oldorderheader
;
create table mck_hvs.oldorderheader(
recvtime datetime NOT NULL
,orderno varchar(20) NOT NULL
)
;
ALTER TABLE mck_hvs.oldorderheader
ADD CONSTRAINT PK_mck_hvs_oldorderheader_orderno PRIMARY KEY CLUSTERED (orderno)
;
GO
--------------------------------------------------------------------------------------------
--Generate some test data (about two years worth working back from today)
--First the old data (not today's)
INSERT mck_hvs.oldorderheader
SELECT top 100000 dateadd(mi,abs(checksum(newid())) %1440,dateadd(dd,-abs(checksum(newid())) %720,getdate()-1)) as recvtime
,right('0000000' + cast(row_number() OVER(ORDER BY (SELECT NULL)) as varchar(20)),7)
+ char(82 + abs(checksum(newid()))%4) + char(82 + abs(checksum(newid()))%4) as orderno--add two random chars from R,S,T,U to the end
FROM sys.columns col1
cross join sys.columns col2
;
--Now today's (assume 500 orders came in)
INSERT mck_hvs.orderheader
SELECT top 500 dateadd(mi,abs(checksum(newid())) %1440,dateadd(dd,datediff(dd,0,getdate()),0)) --add a random number of minutes to midnight last night
,right('0000000' + cast(row_number() OVER(ORDER BY (SELECT NULL)) +100000 as varchar(20)),7)
+ char(82 + abs(checksum(newid()))%4) + char(82 + abs(checksum(newid()))%4) --add two random chars from R,S,T,U to the end
FROM sys.columns col1
cross join sys.columns col2
;
--------------------------------------------------------------------------------------------
WITH yesterday /*all my problems seemed so far away*/as
(
SELECT datepart(hour,old.recvtime) as received_hour
,count(*) as orders_received
FROM mck_hvs.oldorderheader as old
WHERE old.recvtime < dateadd(dd,datediff(dd,0,getdate()),0) --Yesterday
AND old.recvtime >= dateadd(dd,datediff(dd,0,getdate())-1,0)
AND old.orderno not like '%ST' --Note: This is not a SARGable search.
GROUP BY datepart(hour,recvtime)
)
, today as
(
SELECT datepart(hour,ordr.recvtime) as received_hour
,count(*) as orders_received
FROM mck_hvs.orderheader as ordr
WHERE ordr.orderno not like '%ST' --Google "SARG". Trust me.
GROUP BY datepart(hour,ordr.recvtime)
)
SELECT isnull(yesterday.received_hour,today.received_hour) as received_hour
,isnull(yesterday.orders_received,0) as orders_received_yesterday
,isnull(today.orders_received,0) as orders_received_today
FROM yesterday
--FULL JOIN in case there are hours of activity in one table that don't exist in the other table.
FULL JOIN today ON yesterday.received_hour = today.received_hour
;

Displaying Monthly Attendance Date Wise

I need to display attendance data in monthly format using PIVOT. But unable to figure out how it should be done.
Below is my table structure
Attendance:
AttendanceID EmployeeID AttendanceDateTime
Employee:
EmployeeID EmployeeName
Holiday:
HolidayID HolidayDate
Leave:
LeaveID EmployeeID LeaveDateTime IsApproved
I want to display result like below from the data provided in above table
EmployeeName 01-09-2016 02-09-2016 03-09-2016 04-09-2016
A Present Absent Holiday Leave
So the first thing you probably want to do before creating a pivot on dates is figure out what dates you want to pivot. For the purposes of an example, I've just included a way you could get every date within a certain range in this answer but it really depends on what you're looking for.
SELECT *
FROM (
SELECT E.EmployeeID, E.EmployeeName, T.DateToCheck, COALESCE(H.val, A.val, L.val, 'Absent') val
FROM tblEmployee E
CROSS JOIN (
SELECT CAST(DATEADD(DAY, number, '2016-09-01') AS DATE)
FROM master..spt_values
WHERE type = 'P'
AND number <= 3) T(DateToCheck)
LEFT JOIN (SELECT 'Holiday' val, HolidayDate FROM tblHoliday) H ON H.HolidayDate = T.DateToCheck
LEFT JOIN (SELECT 'Present' val, AttendanceDateTime, EmployeeID FROM tblAttendance) A ON CAST(A.AttendanceDateTime AS DATE) = T.DateToCheck AND A.EmployeeID = E.EmployeeID
LEFT JOIN (SELECT 'Leave' val, LeaveDateTime, EmployeeID FROM tblLeave) L ON CAST(L.LeaveDateTime AS DATE) = T.DateToCheck AND L.EmployeeID = E.EmployeeID) T
PIVOT (MAX(val) FOR DateToCheck IN ([2016-09-01], [2016-09-02], [2016-09-03], [2016-09-04])) P;
The basic logic here is that you want to produce your dates to check, compare those dates to each of the different tables (using left joins or outer applies), get only one result (the logic in this answer uses a coalesce to decide which value it'll show), then pivot the result.
EDIT: If you require a PIVOT for a dynamic set of column names (e.g. a dynamic date range), you're going to need to use dynamic SQL. Here's one way you could do it:
DECLARE #SQL VARCHAR(MAX) = '', #dateRange VARCHAR(MAX) = '', #startDate DATE = '2016-09-01', #endDate DATE = '2016-09-05';
SELECT #dateRange += ',' + QUOTENAME(DATEADD(DAY, number, #startDate))
FROM master..spt_values
WHERE type = 'P'
AND DATEADD(DAY, number, #startDate) <= #endDate;
SELECT #dateRange = STUFF(#dateRange, 1, 1, '');
SELECT #SQL = 'SELECT *
FROM (
SELECT E.EmployeeID, E.EmployeeName, T.DateToCheck, COALESCE(H.val, A.val, L.val, ''Absent'') val
FROM tblEmployee E
CROSS JOIN (
SELECT CAST(DATEADD(DAY, number, ''' + CAST(#startDate AS CHAR(10)) + ''') AS DATE)
FROM master..spt_values
WHERE type = ''P''
AND DATEADD(DAY, number, ''' + CAST(#startDate AS CHAR(10)) + ''') <= ''' + CAST(#endDate AS CHAR(10)) + ''') T(DateToCheck)
LEFT JOIN (SELECT ''Holiday'' val, HolidayDate FROM tblHoliday) H ON H.HolidayDate = T.DateToCheck
LEFT JOIN (SELECT ''Present'' val, AttendanceDateTime, EmployeeID FROM tblAttendance) A ON CAST(A.AttendanceDateTime AS DATE) = T.DateToCheck AND A.EmployeeID = E.EmployeeID
LEFT JOIN (SELECT ''Leave'' val, LeaveDateTime, EmployeeID FROM tblLeave) L ON CAST(L.LeaveDateTime AS DATE) = T.DateToCheck AND L.EmployeeID = E.EmployeeID) T
PIVOT (MAX(val) FOR DateToCheck IN (' + #dateRange + ')) P;';
PRINT #SQL;
EXEC(#SQL);
Changing the start and end dates will change the output. You can use the PRINT #SQL to see the actual query.

how can I get data from every month from past one year in t-sql and each month should be in different column

I want data from past 1 year, for example today is 02-05-2014, i need data from May 2013, June 2013..till April 2014 as separate columns. If anybody can help with this code in t-sql that will be very helpful for me. Thanks
ok here i want the data. below is my column
created date
------------
02-05-2013
16-05-2013
05-06-2013
22-07-2013
01-08-2013
09-08-2013
02-09-2013
03-10-2013
19-11-2013
11-12-2013
03-01-2014
29-02-2014
15-03-2014
19-04-2014
I want the result as
May 2013 June 2013 July 2013 August 2013 till April 2014
-------- --------- --------- ----------- ----------
02-05-2013 05-06-2013 22-07-2013 01-08-2013 19-04-2014
16-05-2013 09-08-2013
and also I want to make Columns dynamically which is very important for my query
Although everyone was quick to suggest using PIVOT, that really won't work here because PIVOT would need to aggregate each column into one (max, min, whatever) date for that month and year.
I gave this question some attention because it was actually an interesting challenge. The reality is, this is best done by some reporting tool, such as SSRS, because your output is really a timeline report.
Because of the requirement for dynamic columns and such, I really don't see how this can be done without variables and some dynamic sql, so assuming that is acceptable, the following is tested and will output exactly what you described. It essentially creates 12 CTE tables, each containing the dates for a month and year, (counting backwards from whatever month and year you run the sql). It then creates the report simply by using a FULL OUTER JOIN of all the tables. However, if you full joined just the 12 tables, each column would have its values randomly over several rows with many nulls in betweeen. To line the dates in each column up at the top, it was necessary to add a base table with sequential numbers that each mo/yr table can join on. The sequential numbers are generated up to the max number of dates for any given mo/yr. (Note: with the base number table, a LEFT OUTER JOIN would have sufficed as well...)
This assumes the table name is dbo.MyTable and the date column is CreatedDate:
DECLARE #cteSql nvarchar(MAX) = '';
DECLARE #tblSql nvarchar(MAX) = '';
DECLARE #frmSql nvarchar(MAX) = '';
DECLARE #colNm varchar(10);
DECLARE #tblNm varchar(3);
DECLARE #i int = 0;
/* today's date */
DECLARE #td date = GETDATE();
/* max number of dates per yr/mo */
DECLARE #maxItems int = (SELECT MAX(CNT) FROM (SELECT COUNT(*) AS CNT FROM dbo.MyTable GROUP BY YEAR(CreatedDate), MONTH(CreatedDate)) T)
/* a table of sequential numbers up to the max per yr/mo; this is so the full outer join is laid out neatly */
SET #cteSql = 'WITH T(id) AS( SELECT id = 1 UNION ALL SELECT id + 1 FROM T WHERE id + 1 <= ' + CAST(#maxItems AS varchar(16)) + ')';
/* count down from current date to past 12 months */
WHILE #i > -12
BEGIN
/* a simple name for each CTE: T0, T1, T2 etc */
SET #tblNm = 'T' + CAST((#i*-1) AS varchar(2));
/* rpt column names; [Jan 2014], [Feb 2014] etc */
SET #colNm = '[' + RIGHT(CONVERT(varchar(11), DATEADD(m, #i, #td), 106),8) + ']';
/* each CTE contains a sequential id and the dates belonging to that month and yr */
SET #cteSql += ', ' + #tblNm + '(id, ' + #colNm + ')'
+ ' AS (SELECT ROW_NUMBER() OVER(ORDER BY CreatedDate) AS id, CreatedDate FROM dbo.MyTable WHERE YEAR(CreatedDate) = ' + CAST(YEAR(DATEADD(m, #i, #td)) AS varchar(4))
+ ' AND MONTH(CreatedDate) = ' + CAST(MONTH(DATEADD(m, #i, #td)) AS varchar(2)) + ')';
/* this will eventually be the SELECT statement for the report...just the month columns, not the id */
SET #tblSql = ', ' + #colNm + #tblSql;
/* concatenate all the columns using FULL OUTER JOIN with the first table of simple sequential numbers as the driver */
SET #frmSql += ' FULL OUTER JOIN ' + #tblNm + ' ON T.id = ' + #tblNm + '.id ';
SET #i -= 1;
END
/* put all the sql together */
SET #tblSql = #cteSql + ' SELECT' + STUFF(#tblSql, 1, 1, '') + ' FROM T ' + #frmSql
/* view the generated sql */
-- SELECT #tblSql AS X
/* this should generate the report you described above, showing the last 12 months from whatever date you run it */
EXECUTE (#tblSql)
Output:
Jun 2013 Jul 2013 Aug 2013 Sep 2013 Oct 2013 Nov 2013 Dec 2013 Jan 2014 Feb 2014 Mar 2014 Apr 2014 May 2014
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
2013-06-05 2013-07-22 2013-08-01 2013-09-02 2013-10-03 2013-11-19 2013-12-11 2014-01-03 2014-02-28 2014-03-15 2014-04-19 NULL
2013-06-07 NULL 2013-08-09 NULL NULL NULL NULL NULL NULL NULL NULL NULL
NULL NULL 2013-08-10 NULL NULL NULL NULL NULL NULL NULL NULL NULL
As it turns out, the sql generated is conceptually similar to what #Hogan suggested, although I did not realize it at first. It really just adds the dynamic naming plus the segregation by yr/mo and not just month.
Here is a way to do it without a dynamic pivot. I only did it for 2013, you can see what is needed to add more columns:
(working fiddle: http://sqlfiddle.com/#!6/d9797/1)
with nums as
(
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =1
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =2
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =3
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =4
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =5
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =6
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =7
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =8
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =9
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =10
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =11
union all
select [create date],
MONTH([create date]) as M,
ROW_NUMBER() OVER (ORDER BY [create date] ASC) as RN
from table1
where MONTH([create date]) =12
),maxrn as
(
select MAX(RN) as maxnum from nums
), rowNumbers as
(
select 1 as RN
union all
select RN+1 AS RN
from rowNumbers
where RN < (select maxnum from maxrn)
)
SELECT
nJan.[create date] as [Jan 2013],
nFeb.[create date] as [Feb 2013],
nMar.[create date] as [Mar 2013],
nApr.[create date] as [Apr 2013],
nMay.[create date] as [May 2013],
nJun.[create date] as [Jun 2013],
nJul.[create date] as [Jul 2013],
nAug.[create date] as [Aug 2013],
nSep.[create date] as [Sep 2013],
nOct.[create date] as [Oct 2013],
nNov.[create date] as [Nov 2013],
nDec.[create date] as [Dec 2013]
FROM rowNumbers n
LEFT JOIN nums nJan ON n.RN = nJan.RN and nJan.M = 1
LEFT JOIN nums nFeb ON n.RN = nFeb.RN and nFeb.M = 2
LEFT JOIN nums nMar ON n.RN = nMar.RN and nMar.M = 3
LEFT JOIN nums nApr ON n.RN = nApr.RN and nApr.M = 4
LEFT JOIN nums nMay ON n.RN = nMay.RN and nMay.M = 5
LEFT JOIN nums nJun ON n.RN = nJun.RN and nJun.M = 6
LEFT JOIN nums nJul ON n.RN = nJul.RN and nJul.M = 7
LEFT JOIN nums nAug ON n.RN = nAug.RN and nAug.M = 8
LEFT JOIN nums nSep ON n.RN = nSep.RN and nSep.M = 9
LEFT JOIN nums nOct ON n.RN = nOct.RN and nOct.M = 10
LEFT JOIN nums nNov ON n.RN = nNov.RN and nNov.M = 11
LEFT JOIN nums nDec ON n.RN = nDec.RN and nDec.M = 12
ORDER BY n.RN ASC
OOOPS this already have an answer T_T,
but try this if you have a free time. :)
use a lot of things in this case:
CTE
STUFF
CONVERT
SUBSTRING
declare #xCol nvarchar(max);
--Begin create column
with cte as
(
select 1 as id,
aa.month as mm, aa.Year
--,aa.xmonth as mmm
, aa.ord
from
(
select
xdate
,Year(xdate) as Year
--,month(xdate) as xmonth
, substring(convert(nvarchar(max),xdate,106),3,len(convert(nvarchar(max),xdate,106))) as month
,convert(nvarchar(6), xdate,112) as ord
from tempData vv
) aa
group by aa.ord, aa.month,aa.Year
--order by aa.Year
)
select
distinct
--c.id,
#xCol = stuff(
(
select ',' + c2.mm
from cte c2
where c.id = c2.id
for xml path ('')
),1,0,''
)
from cte c
;
set #xCol= SUBSTRING(#xCol,2, len(#xCol))
select #xCol = '[' + replace(#xCol,',','],[') + ']'
--select #xCol as '#columns', len(#xCol)
--END CREATE COLUMNS
--CREATE INPUT STRING
Declare #tbl_inputstr table
(
id int,
xstr nvarchar(max)
)
;
with cte as
(
select
a.xdate, a.month
,row_number() over(partition by a.month order by a.xdate) as xrow
from
(
select
xdate
,Year(xdate) as Year
,month(xdate) as xmonth
,convert(nvarchar(6),xdate,112) as month2
, substring(convert(nvarchar(max),xdate,106),3,len(convert(nvarchar(max),xdate,106))) as month
from tempData
) a
)
insert into #tbl_inputstr(id,xstr)
select distinct c.xrow as id,
' Insert into #tempData (' + substring(stuff(
(
select ',[' + cast(c2.month as nvarchar(max)) + ']'
from cte c2
where c.xrow = c2.xrow
for xml path ('')
),1,0,''
),2,len(stuff(
(
select ',[' + cast(c2.month as nvarchar(max)) + ']'
from cte c2
where c.xrow = c2.xrow
for xml path ('')
),1,0,''
))) + ')'
+' Values(' + Substring(stuff(
(
select ',''' + cast(c2.xdate as nvarchar(max)) + ''''
from cte c2
where c.xrow = c2.xrow
for xml path ('')
),1,0,''
),2,len(stuff(
(
select ',''' + cast(c2.xdate as nvarchar(max)) + ''''
from cte c2
where c.xrow = c2.xrow
for xml path ('')
),1,0,''
))) + ')'
from cte c
order by c.xrow;
select * from #tbl_inputstr
Declare #inputStr nvarchar(max)
select #inputStr =
substring(stuff
(
(
select ';' + xstr
from #tbl_inputstr
for xml path('')
),1,0,''
),2, len(stuff
(
(
select ';' + xstr
from #tbl_inputstr
for xml path('')
),1,0,''
))
)
select #inputStr= 'Declare #tempData Table (' +replace(#xCol,']', '] nvarchar(max)') + ');' + #inputStr
+ '; select ' + #xCol
+ ' from #tempData'
exec(#inputStr)
--END INPUT STRING

MS SQL distinct function

I have the query below
SELECT distinct
count(patient.id)
CAST(YEAR(completiondate) AS VARCHAR(4)) + '-' + CAST(MONTH(completiondate) AS VARCHAR(2)) AS Mjesec
FROM ....
WHERE
incident.completionDate Between Convert(smalldatetime, '01/10/2007', 103) and Convert(smalldatetime, '01/11/2013', 103)
and servicecharges.serviceid in (47)
and incident.status != 6
and ServiceRequestDescription LIKE 'something'
and chargeDescr = 'test'
group by CAST(YEAR(completiondate) AS VARCHAR(4)) + '-' + CAST(MONTH(completiondate) AS VARCHAR(2))
the result i take, have unique rows of patient.id AND Year-Month. That means that i can have multiple rows with the same patient.id and several year-month.
how can i change that query, in order to take the results, with each patient.id only once, with the first completiondate with the specific elements?
I guess it should be:
SELECT
patient.id
MIN(
CAST(YEAR(completiondate) AS VARCHAR(4)) + '-' + CAST(MONTH(completiondate) AS VARCHAR(2))
)
AS Mjesec
FROM ....
WHERE
incident.completionDate Between Convert(smalldatetime, '01/10/2007', 103) and Convert(smalldatetime, '01/11/2013', 103)
and servicecharges.serviceid in (47)
and incident.status != 6
and ServiceRequestDescription LIKE 'something'
and chargeDescr = 'test'
group by patient.id
Please Try it
WITH CTE AS
(
SELECT *,RN=ROW_NUMBER() OVER (PARTITION BY patient ORDER BY patient DESC) FROM tablename
)
select * from CTE where RN>1

how to use PIVOT to get required results [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
convert one row into columns.
This is my query.
DECLARE #temp TABLE
(
MonthName VARCHAR(10),
[Year] VARCHAR(10),
StatusTypeId INT,
StatusTypeName VARCHAR(50),
StatusCount INT
)
INSERT INTO #temp
SELECT
CONVERT(varchar(3), DATENAME(month, w.ExpectedStartDate)) as MonthName,
datepart(yyyy, w.ExpectedStartDate) as [Year],
w.StatusTypeId,
st.StatusTypeName,
COUNT(ISNULL(w.StatusTypeId, 0)) AS StatusCount
FROM
Worksheet w LEFT OUTER JOIN
StatusType st ON st.StatusTypeId = w.StatusTypeId
WHERE w.ProjectId = 20
AND CONVERT(varchar(3), DATENAME(month, w.ExpectedStartDate)) between ('feb') AND ('mar')
GROUP BY
datepart(yyyy, w.ExpectedStartDate),
CONVERT(varchar(3), DATENAME(month, w.ExpectedStartDate)),
w.StatusTypeId,
st.StatusTypeName
SELECT ISNULL(((CONVERT(VARCHAR(5), [Year])) + '-' + MonthName), 'Unknown') AS MonthName,
ISNULL(StatusTypeName, 'Unknown') AS StatusTypeName,
StatusCount
FROM #temp
I want result like this.
Please guide me.
Thanks.
Eg.
select
*
from
(
select
monthname,statustypename
from yourtable
) DataTable
PIVOT
(
SUM(statuscount)
FOR statustypename
IN (
[tobescheduled],[complete]
)
) PivotTable
Also check the link
http://geekswithblogs.net/lorint/archive/2006/08/04/87166.aspx