Count of rows for 2 days - sql-server

My data is in below format:
employee order id date
a 123 01/06/2013
b 124 02/06/2013
a 125 02/06/2013
a 129 02/06/2013
I need the data in below format:
employee day 1 day 2
a 1 2
b 0 1

Try this one -
DECLARE #temp TABLE
(
dtStart DATETIME
, employees CHAR(1)
)
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('b','02/06/2013')
SELECT
employees
, day1 = COUNT(CASE WHEN DAY(dtStart) = 1 THEN 1 END)
, day2 = COUNT(CASE WHEN DAY(dtStart) = 2 THEN 1 END)
FROM #temp
--WHERE dtStart BETWEEN '01/06/2013' AND '30/06/2013'
GROUP BY employees

Something along these lines should work (depending on whether you have a fixed amount of days or not):
select employee,
SUM(CASE WHEN date = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN date = '02/06/2013' THEN 1 ELSE 0 END) as day2
from table
group by employee

select distinct employees,
SUM(CASE WHEN dtStart = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN dtStart = '02/06/2013' THEN 1 ELSE 0 END) as day2
from yourTable
group by dtStart,employees
see your demo

Related

How can separate morning and evening shifts patients with gender wise using SQL stored procedure

I want to separate the morning and evening patient checked-in count gender-wise and also if gender age less then show the Female child and M child on the basis of gender.
SELECT
COUNT(ch.EnteredOn) AS counter,
CONVERT(date, ch.EnteredOn) AS sessionDay,
SUM(CASE WHEN CAST(CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) < 12 THEN 1 ELSE 0 END) AS 'Morning',
SUM(CASE WHEN CAST(CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) >= 12 THEN 1 ELSE 0 END) AS 'Evening',
SUM(CASE WHEN p.Gender = 1 THEN 1 ELSE 0 END) AS Male,
SUM(CASE WHEN p.Gender = 2 THEN 1 ELSE 0 END) AS Fmale,
SUM(CASE WHEN DATEDIFF(hour, P.DOB, GETDATE()) / 8766 <= 18
AND P.Gender = 1 THEN 1 ELSE 0 END) AS MChild,
SUM(CASE WHEN DATEDIFF(hour, P.DOB, GETDATE()) / 8766 <= 18
AND P.Gender = 2 THEN 1 ELSE 0 END) AS FChild
FROM
Patient.CheckIn ch
INNER JOIN
Patient.Patients P ON ch.PatientId = p.PatientId
GROUP BY
Ch.EnteredOn
I have only three columns like Gender, Time and DOB. Gender id 1 shows the male and Gender id 2 is using for females.
enter image description here
SELECT convert(date, ch.EnteredOn) AS sessionDay, CAST( CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) <12 as morning, count(ch.EnteredOn) AS counter
,sum(case when p.Gender=1 Then 1 ELSE 0 end) as Male
,sum(case when p.Gender=2 Then 1 ELSE 0 end) as Fmale
,Sum( case when DATEDIFF(hour,P.DOB,GETDATE())/8766<=18 AND P.Gender=1 Then 1 ELSE 0 end ) as MChiled
,Sum( case when DATEDIFF(hour,P.DOB,GETDATE())/8766<=18 AND P.Gender=2 Then 1 ELSE 0 end ) as FChiled
FROM Patient.CheckIn ch
inner join Patient.Patients P on ch.PatientId=p.PatientId
Group by Ch.EnteredOn
Group BY can be
Group by convert(date, ch.EnteredOn) AS sessionDay, CAST( CONVERT(CHAR(2), ch.EnteredOn, 108) AS INT) <12

SQL Pivot to be used in a View

I am trying to create a view that will sum the total hours of different work types, as well as the quantity of different products used to a RefNumber.
I have successfully pivoted and summed the hours of work grouped by RefNumber, but now I am scratching my head on how to sum the total product use by Ref Number.
Sample Data
Download Excel of data
Keep in mind, on some RefNumbers, there will be multiple entries of the same ProductID. We may have had a few guys using the same product in different quantities.
Here is what I am trying to the Pivot the data too:
Pivot Data
So far, I have been able to accomplish summing the hours of each work type, and pivoting that data into a single line item grouped by the Ref Number using the following SQL code:
SELECT RefNumber,
SUM (CASE WHEN WorkType = 'Blast' THEN THours ELSE NULL END) AS TBlast,
SUM (CASE WHEN WorkType = 'Wheel' THEN THours ELSE NULL End) As TWheel,
SUM (CASE WHEN WorkType = 'Painting' THEN THours ELSE NULL END) AS TPainter,
SUM (CASE WHEN WorkType = 'Mask/Prep' THEN Thours ELSE NULL END) As TMask,
SUM (CASE WHEN WorkType = 'Demask/Touch Up' THEN Thours ELSE NULL END) As TDMask,
SUM (CASE WHEN WorkType = 'Handling: Raw' THEN THours ELSE NULL END) As TRHand,
SUM (CASE WHEN WorkType = 'Handling: Product' THEN Thours ELSE NULL END) As TPHand,
SUM (CASE WHEN WorkType = 'Wheel:Assist' THEN Thours ELSE NULL END) As TAWheel,
SUM (CASE WHEN WorkType = 'Metalizing' THEN Thours ELSE NULL END) As TMetal
FROM (
SELECT [RefNumber], [WorkType], SUM (Hours)/60 As THours
FROM [dbo].[Vw_Beta_CostLog]
GROUP BY RefNumber, WorkType
) sub
GROUP BY RefNumber
ORDER BY RefNumber
Any Ideas on how to modify this code base to Pivot the the distinct product ID's into there own column, and sum the use of those products in a second column?
Also, I want to be able to use this as a view, so I am trying to avoid dynamic pivots.
EDIT: Forgot to mention, there will be at most 4 unique products used per ref number.
RAW DATA
GUID EmpName RefNumber DateInt Hours WorkType ProductID PQty
P-3468 Gary Hahn 114204 20181008 132 Painting NULL NULL
P-3473 Gary Hahn 114204 20181009 204 Painting NULL NULL
P-3475 Gary Hahn 114204 20181009 120 Painting NULL NULL
F-31915 Jose Flores 114204 20181007 60 Handling: Raw NULL NULL
F-31941 Jose Flores 114204 20181008 30 Handling: Raw NULL NULL
F-31951 Chris Pollock 114204 20181008 30 Handling: Raw NULL NULL
F-32076 Chris Pollock 114204 20181010 120 Handling: Product NULL NULL
F-32109 Chris Pollock 114204 20181011 90 Handling: Product NULL NULL
F-32301 Daryl Underwood 114204 20181015 15 Handling: Product NULL NULL
B-6594 David Martinez 114204 20181007 150 Blast NULL NULL
B-6599 Emiliano Barrios 114204 20181008 66 Blast NULL NULL
B-6617 Jose Molina 114204 20181009 30 Blast NULL NULL
P-3468 Gary Hahn 114204 20181008 NULL Primer 11 3
P-3473 Gary Hahn 114204 20181009 NULL Intermediate 890 2
P-3475 Gary Hahn 114204 20181009 NULL Finish 134HG 2
Output I am looking for
RefNumber Blast Painting Handling: Raw Handling: Product Product1 P1Qty Product2 P2Qty Product3 P3Qty
114204 246 456 120 225 11 3 890 2 134HG 2
You can "pivot" non-numeric data by using MAX() instead of SUM() and continue to use case expressions as you are already doing.
SELECT
RefNumber
, SUM (CASE WHEN WorkType = 'Blast' THEN Hours/60 ELSE NULL END) AS TBlast
, SUM (CASE WHEN WorkType = 'Wheel' THEN Hours/60 ELSE NULL End) As TWheel
, SUM (CASE WHEN WorkType = 'Painting' THEN Hours/60 ELSE NULL END) AS TPainter
, SUM (CASE WHEN WorkType = 'Mask/Prep' THEN Hours/60 ELSE NULL END) As TMask
, SUM (CASE WHEN WorkType = 'Demask/Touch Up' THEN Hours/60 ELSE NULL END) As TDMask
, SUM (CASE WHEN WorkType = 'Handling: Raw' THEN Hours/60 ELSE NULL END) As TRHand
, SUM (CASE WHEN WorkType = 'Handling: Product' THEN Hours/60 ELSE NULL END) As TPHand
, SUM (CASE WHEN WorkType = 'Wheel:Assist' THEN Hours/60 ELSE NULL END) As TAWheel
, SUM (CASE WHEN WorkType = 'Metalizing' THEN Hours/60 ELSE NULL END) As TMetal
, MAX (CASE WHEN rn = 1 THEN WorkType END) As WorkType1
, MAX (CASE WHEN rn = 1 THEN ProductID END) As Product1
, MAX (CASE WHEN rn = 1 THEN PQty END) As Qty1
, MAX (CASE WHEN rn = 2 THEN WorkType END) As WorkType2
, MAX (CASE WHEN rn = 2 THEN ProductID END) As Product2
, MAX (CASE WHEN rn = 2 THEN PQty END) As Qty2
, MAX (CASE WHEN rn = 3 THEN WorkType END) As WorkType3
, MAX (CASE WHEN rn = 3 THEN ProductID END) As Product3
, MAX (CASE WHEN rn = 3 THEN PQty END) As Qty3
FROM (
SELECT
[RefNumber]
, [WorkType]
, [ProductID]
, Hours
, PQty
, ROW_NUMBER() OVER (PARTITION BY RefNumber, case when ProductID IS NULL then 0 else 1 end ORDER BY ProductID) rn
FROM [Vw_Beta_CostLog]
) sub
GROUP BY
RefNumber
ORDER BY
RefNumber
Note that you cannot create a view which dynamically increases or decreases the number of columns based on how many products are used.
see online demo: https://rextester.com/SBQUP24417

How to fetch record from two tables specify column name based on second table row records

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

check all the values of a column

select all the departments having students with even roll number
Dept No Roll No Student Name
1 1 lee
1 2 scott
2 2 scott
2 4 smith
1 4 smith
This should result in DEpt no 2 as it has only students with roll number divisible by 2
Another(imo easy and lightweight) way is using NOT EXISTS and DISTINCT:
SELECT DISTINCT [Dept No]
FROM dbo.TableName t
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.TableName t2
WHERE t.[Dept No] = t2.[Dept No]
AND t2.[Roll No] % 2 = 1
)
Demo
If there is no odd number all must be even.
You can use GROUP BY with HAVING like this.
Query
SELECT [Dept No]
FROM departments
GROUP BY [Dept No]
HAVING SUM(CASE WHEN [Roll No] % 2 = 0 THEN 1 ELSE 0 END) > 1
AND SUM(CASE WHEN [Roll No] % 2 = 1 THEN 1 ELSE 0 END) = 0
Explanation
The query returns the departments if there a rollno which is even using SUM(CASE WHEN [Roll No] % 2 = 0 THEN 1 ELSE 0 END) > 1. If there is any rollno with odd roll no, SUM(CASE WHEN [Roll No] % 2 = 1 THEN 1 ELSE 0 END) will return non zero sum and that department will be excluded.
declare #t table (Dept int,Rno int,Student varchar(10))
insert into #t (Dept,Rno,Student)values (1,1,'lee'),(1,2,'scott'),(2,2,'scott'),(2,4,'smith'),(1,4,'smith')
SELECT Dept,Rno,Student
FROM (SELECT ROW_NUMBER () OVER (ORDER BY Rno DESC) row_number, Dept,Rno,Student
FROM #t) a WHERE (row_number%2) = 0

How to add Totals in SQL

I am trying to get the totals of each month as of YTD (Years to date) Can someone please help me figure out how to integrate this in my query? thank you This is what I have so far.
DECLARE #Year int
set #Year = 2013
select a.first_name, a.last_name
, COUNT(CASE WHEN MONTH(b.Funded_date) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(b.Funded_date) = 2 THEN 1 ELSE NULL END) February
, COUNT(CASE WHEN MONTH(b.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(b.Funded_date) = 4 THEN 1 ELSE NULL END) April
From tContact a Join tContract b ON a.contact_id = b.contract_id
Group by a.first_name, a.last_name
This is just an example of how you could count up rows that fall under a certain month.
SELECT MONTH(b.Funded_date) AS 'MonthNum',
COUNT(*) AS 'Total'
FROM Table AS b
WHERE YEAR(b.Funded_date) = 2014
GROUP BY MONTH(b.Funded_date)
Hopefully this will help you with your query.
Thanks
What I tried to do here is create an upper bound record for each month in tContract then join that back into the query you already had. It is joined on dates that are between the beginning of the year and the current month.
DECLARE #Year int
set #Year = 2013
select Ms.thismonth, count(B.thing_You_are_Totalling) from (
select thisMonth = dateadd(month,datediff(month,0,Funded_date),0)
from tContract
where moid = 2005405
and year(Funded_date) = #Year
group by dateadd(month,datediff(month,0,Funded_date),0)
) Ms
inner join (select * from tContact a inner join tContract ON a.contact_id = tContract.contract_id) B
on B.Funded_date >=dateadd(year,datediff(year,0,B.Funded_date),0) -- beginning of year
and B.Funded_date <= Ms.thisMonth -- this month
where year(B.Funded_date) = #Year -- restrict to only this year
group by thisMonth, first_name, last_name
I don't have your full table definition so there might be some issues (maybe a SqlFiddle is in order)
Not sure if this is what you are asking for.
select a.first_name, a.last_name
, COUNT(CASE WHEN MONTH(b.Funded_date) = 1 THEN 1 ELSE NULL END) January
, COUNT(CASE WHEN MONTH(b.Funded_date) = 2 THEN 1 ELSE NULL END) February
, COUNT(CASE WHEN MONTH(b.Funded_date) = 3 THEN 1 ELSE NULL END) March
, COUNT(CASE WHEN MONTH(b.Funded_date) = 4 THEN 1 ELSE NULL END) April
, COUNT(*) TotalCount
, SUM(CASE WHEN MONTH(b.Funded_date) = 1 THEN Amount ELSE NULL END) JanuaryAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 2 THEN Amount ELSE NULL END) FebruaryAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 3 THEN Amount ELSE NULL END) MarchAmount
, SUM(CASE WHEN MONTH(b.Funded_date) = 4 THEN Amount ELSE NULL END) AprilAmount
From tContact a Join tContract b ON a.contact_id = b.contact_id
WHERE YEAR(b.Funded_date) = #Year
Group by a.first_name, a.last_name
How about this:
declare #year int = 2013
select a.first_name
, a.last_name
, month(b.Funded_date) [Month]
, datename(month, dateadd(month, month(date_of_birth_dt), - 1)) [MonthName]
, count(month(b.Funded_date)) [Total]
from tContact a
where a.[Year] = #year
group by a.first_name, a.last_name, month(b.Funded_date)
It returns the total of each Month for the year 2013. a.[Year] might not the the name of the field that you have so adjust accordingly. Also, [Month] returns numeric value for month.
Use the Count(*) As Total function. I'm sure this will help you
SELECT MONTH(b.Funded_date) AS 'MonthNum',
COUNT(*) AS 'Total'
FROM Table AS b
WHERE YEAR(b.Funded_date) = 2014
GROUP BY MONTH(b.Funded_date)

Resources