For LOOP in SQL Server - sql-server

Total EmpId in Database = 74.
Active Days for September 2013 in Databse = 22
I want to segregate the dates when the employee was not filled the production in MIS_Opus table.
Since FULL OUTER Join was not worked, I m using the except query. Through this query, I can get the unfilled dates for each employee by passing the empid thru c# function. For that loop will going to SQL & back to C# for 74 times. Please let me know how can I get the unfilled dates for all employees at one shot in SQL itself. I m using SQL 2012 and VS 2012 c#.
Thank you,
select _Date from MIS_BM_Calendar c
where c.Month = 'September 2013' and c.DayShiftStatus = 'active'
except
select _Date from MIS_Opus o
where o.EmpId=#Empid

One way is to build a list of all employee + day combinations using a cross join. Then you can use a left join to check if there is an employee entry for that day.
select days._Date as TheDay
, emps.EmpId as EmployeeWithMissingEntry
from (
select distinct _Date
from MIS_BM_Calendar
where Month = 'September 2013'
and DayShiftStatus = 'active'
) days
cross join -- One row for each combination of employee and date
(
select distinct EmpId
from MIS_Opus
) emps
left join
MIS_Opus o
on o._Date = days._Date
and o.EmpId = emps.EmpId
where o._Date is null -- Employee entry for day not found

Related

Running 3-Tier T-SQL Query for Report

First question here so please excuse any mistakes...
I am trying to write a SQL Query for an SSRS report and I am totally confused when it comes to my joins.
Background: I have 3 tables that are relevant
Publishers - This is essentially a list of people
Publisher Reports - This is a list of records (related to the Publisher table) that details the work they have completed in a month period.
Report Months - This is a list of records (related to the Publisher Reports table) that relates to a specific month and year. On these records they have an indicator to show whether they relate to the previous six month period.
What i am trying to do is get a list of Publishers who have not submitted a publisher report that is related to a Report Month record within the last 6 months. My desired output is a list of Publishers in on column with the Report Month(s) that they are missing in the next column.
I am really struggling how to do it... I had thought of it as a three step process...
--STEP 1 - Get list of report months that are included in the last 6 months
WITH ACTIVE6MREPM AS
(
SELECT r.jajw_name,
r.jajw_CalendarDate
FROM jajw_reportmonthBase r
WHERE r.jajw_IncludedIn6MonthReport = '1'
),
--STEP 2 - Get list of all publishers
ACTIVEPUBS AS
(
SELECT c.FullName,
c.ContactId
FROM ContactBase c
WHERE c.statecode = '0'
AND c.jajw_CongregationAssignment != 640840001
AND c.jajw_CongregationAssignment != 640840006
AND c.jajw_CongregationAssignment != 640840005
--AND q.jajw_FieldServiceGroups = (#Field_Service_Group)
),
--STEP 3 - Get List of Publisher Reports for the selected Report Months
RELEVANTREPORTS AS
(
SELECT r.jajw_reportId AS Publisher_Report_GUID,
r.jajw_PublisherId AS Publisher_GUID,
r.jajw_ReportMonthId AS ReportMonth_GUID,
m.jajw_name AS ReportMonth_Name
FROM jajw_reportBase r
INNER JOIN jajw_reportmonthBase m ON r.jajw_ReportMonthId = m.jajw_reportmonthId
WHERE r.jajw_ReportPeriod6Month = '1'
ORDER BY m.jajw_CalendarDate
After these three, I want to create my list as described above and this is the bit that has me stumped! Any help would be greatly appreciated!
Thanks!
I think you can shorten your code a lot... here's a shot at it without having test data... be sure to read the comments and add in the join condition and check the where clause.
with cte as(
SELECT r.jajw_reportId AS Publisher_Report_GUID,
r.jajw_PublisherId AS Publisher_GUID,
r.jajw_ReportMonthId AS ReportMonth_GUID,
m.jajw_name AS ReportMonth_Name,
c.FullName,
c.ContactId
FROM jajw_reportBase r
INNER JOIN jajw_reportmonthBase m ON
r.jajw_ReportMonthId = m.jajw_reportmonthId
INNER JOIN ContactBase c on --what ever condition is appropiate
WHERE r.jajw_ReportPeriod6Month = '1'
and m.jajw_IncludedIn6MonthReport = '1' --maybe put this here, or does the above do the same thing?
ORDER BY m.jajw_CalendarDate)
select
p2.FullName,
p2.ReportMonth_Name
from cte p
right join(select distinct
ReportMonth_Name, FullName
from ContactBase
left join jajw_reportmonthBase on 1=1) p2 on p2.FullName = p.FullName and p2.ReportMonth_Name = p.ReportMonth_Name
where
ContactId in (select ContactId from cte group by ContactId having count(distinct ReportMonth_GUID) < 6)
and p.FullName is null
Here is an example using test data.
declare #pub table (pubname varchar(56), ReportMonthName varchar(16))
insert into #pub (pubname,ReportMonthName) values
('a','Jan'),
('a','Feb'),
('a','Mar'),
('a','Apr'),
--publisher a is missing May and Jun
('b','Jan'),
('b','Feb'),
('b','Mar'),
('b','Jun')
--publisher b is missing Apr and May
declare #dt table (ReportMonthName varchar(16))
insert into #dt (ReportMonthName) values
('Jan'),
('Feb'),
('Mar'),
('Apr'),
('May'),
('Jun')
select
p2.pubname
,p2.ReportMonthName
from #pub p
right join(
select distinct
p.pubname
,d.ReportMonthName
from #pub p
left join #dt d on 1=1)p2 on p2.pubname = p.pubname and p2.ReportMonthName = p.ReportMonthName where p.pubname is null

How to display only the MAX results from a query

I am new to writing MS SQL queries and I am trying to display only the record with the highest field named RecordVersion.
Below is the query that works but displays all records:
SELECT
PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
Here are the query results:
PriceProgramID EffectiveDateTime Price PLU Descr LastUpdate LastUpdatedBy RecordVersion PriceScheduleUniqueID
1 2016-03-22 00:00:00.000 35.00 SLS10100103 Architecture Adult from NP POS 2015-01-22 07:53:15.000 GX70,83 9 569
1 2016-03-22 00:00:00.000 32.00 SLS10100103 Architecture Adult from NP POS 2014-02-25 16:22:46.000 GX70,83 5 86180
The first line of the results has RecordVersion being 9 and the second line results is 5, I only want the higher record displaying, the one that returned RecordVersion = 9.
Every time I try to use the MAX command I get errors or the group by and I have tried every example I could find on the web but nothing seems to work.
Using MS SQL 2012.
Thanks,
Ken
Try the following query which attempts to solve your problem by ordering the returned rows by RecordVersion DESC and then SELECTs just the first row.
SELECT TOP 1
PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
ORDER BY
RecordVersion DESC
All group by columns should be in select ,that's the rule of group by.How group by works is for every distinct combination of group by columns,arrange remaining columns into groups,so that any aggregation can be applied,in your case I am not sure what group by columns are unique with out test date.here is one version which use row number which gives you the output desired
Remember ,order by last updated date is the one which decides rows order and assign numbers
WITH CTE
AS
(
SELECT PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID,
ROW_NUMBER() OVER (PARTITION BY PriceSchedules.RecordVersion ORDER BY PriceSchedules.LastUpdatedBy) AS RN
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
)
SELECT * FROM CTE WHERE RN=1

Not every row is shown in a query

I have a query to calculate the number of transactions and the number of payments in my table. These counts are based on data in separated tables. I need to group the results by year and the week of year. The dates are coming also from a separate table. I add the week values in an union of the payments and transactions in a with clause and do afterwards the calculation.
WITH CHART_DATES
AS (
SELECT DD.CAL_YEAR, DD.WEEK_OF_YEAR
FROM DIM_DATE DD
RIGHT JOIN FACT_PAY_PAYMENT FPP ON DD.ID = FPP.REQUESTED_EXECUTION_DATE_ID
GROUP BY DD.CAL_YEAR, DD.WEEK_OF_YEAR
UNION
SELECT DD.CAL_YEAR, DD.WEEK_OF_YEAR
FROM DIM_DATE DD
RIGHT JOIN FACT_AS_BALANCE FAB ON DD.ID = FAB.BALANCE_DATE_ID
GROUP BY DD.CAL_YEAR, DD.WEEK_OF_YEAR
)
SELECT
CD.WEEK_OF_YEAR,
CD.CAL_YEAR,
COALESCE(COUNT(DISTINCT FPP.ID), 0) AS PAYMENTS,
COALESCE(COUNT(DISTINCT FAB.ACCOUNT_STATEMENT_ID), 0) AS STATEMENTS
FROM FACT_PAY_PAYMENT FPP
RIGHT JOIN DIM_DATE DD ON FPP.REQUESTED_EXECUTION_DATE_ID = DD.ID
FULL JOIN FACT_AS_BALANCE FAB ON DD.ID = FAB.BALANCE_DATE_ID
RIGHT JOIN CHART_DATES CD ON DD.CAL_YEAR = CD.CAL_YEAR
AND DD.WEEK_OF_YEAR = CD.WEEK_OF_YEAR
INNER JOIN DIM_AS_CHARACTERISTICS DAC ON FAB.BALANCE_TYPE_ID = DAC.ID
WHERE DAC.TRANSACTION_INTRADAY_FLAG = 'N'
GROUP BY CD.CAL_YEAR, CD.WEEK_OF_YEAR
I added following data in my tables:
Week 42 of 2015 has 1 payment and 2 transactions
Week 41 of 2015 has 1 payment and 0 transactions
After executing the query, I receive following result:
Wrong result
What is wrong in my query and how to fix it?

Left join not giving all record Whats wrong with my query [duplicate]

This question already has answers here:
SQL Server left joining
(2 answers)
Closed 7 years ago.
When I do a left outer join, I expect to get all the records that the query would return all record form the left table which not matched with the right table.
I want to select the record even the month data is not available in table. Suppose I have one record for five month. So when I will execute the my query i want total 12 record [left outer join] with 0 values form right table[client_service] table.
my Query is
SELECT YEAR(CLIENT_SERVICE.cliserv_effective_date) As Year
, MonthsTable.MonthName As Month
, COUNT(CLIENT_SERVICE.cliserv_id) As ClientsInService
FROM MonthsTable
left outer join CLIENT_SERVICE
ON MonthsTable.MonthName = DATENAME(month,CLIENT_SERVICE.cliserv_effective_date)
WHERE CLIENT_SERVICE.serv_id = 24
AND CLIENT_SERVICE.cliserv_status = 'Active'
AND YEAR(CLIENT_SERVICE.cliserv_effective_date) BETWEEN 2014 AND 2015
GROUP BY YEAR(CLIENT_SERVICE.cliserv_effective_date)
, DATENAME(month,CLIENT_SERVICE.cliserv_effective_date)
, [MonthsTable].MonthName
, MONTH(CLIENT_SERVICE.cliserv_effective_date)
ORDER BY YEAR(CLIENT_SERVICE.cliserv_effective_date)
, MONTH(CLIENT_SERVICE.cliserv_effective_date);
Thanks in advance!!!
You have column of the right table in the where clause. put it in the on clause:
SELECT YEAR(CLIENT_SERVICE.cliserv_effective_date) As Year,
MonthsTable.MonthName As Month, COUNT(CLIENT_SERVICE.cliserv_id) As ClientsInService
FROM MonthsTable left outer join CLIENT_SERVICE ON MonthsTable.MonthName = DATENAME(month,CLIENT_SERVICE.cliserv_effective_date) and CLIENT_SERVICE.serv_id = 24
AND CLIENT_SERVICE.cliserv_status = 'Active'
AND YEAR(CLIENT_SERVICE.cliserv_effective_date) BETWEEN 2014 AND 2015
GROUP BY YEAR(CLIENT_SERVICE.cliserv_effective_date), DATENAME(month,CLIENT_SERVICE.cliserv_effective_date),
[MonthsTable].MonthName,MONTH(CLIENT_SERVICE.cliserv_effective_date)
ORDER BY YEAR(CLIENT_SERVICE.cliserv_effective_date),
MONTH(CLIENT_SERVICE.cliserv_effective_date)

sum values for most recent month

I’m working with 2 tables, t_funds and t_psg2_nav.
In the t_funds table, the relevant columns are fundnum and br_cd
In t_psg2_nav, the relevant columns are calcdate, return_active_daily, and fundnum
Basically I need a query that sums the return_active_daily per fund for the most recent month. I think I need to use a JOIN clause, but that’s a little stetch for me right now. Here’s what I have… the t_funds table i'm using is only for switching between fundnum and br_cd (a name)... its easier for me that way.
SELECT funds.br_cd AS 'Fund Ticker'
, Month(nav.calcdate) AS 'Month'
, SUM(nav.return_active_daily) AS 'MTD Tracking'
FROM dbo.t_psg2_nav AS nav
, t_funds AS funds
INNER JOIN (SELECT fundnum
,month(max(calcdate)) AS calcdate
FROM dbo.t_psg2_nav
GROUP BY fundnum
) AS nav1
ON nav.fundnum = nav1.fundnum
AND nav.calcdate = nav1.calcdate
WHERE funds.fundnum = nav.fundnum
AND funds.fund_type LIKE 'ETF'
Append this to the end of your SQL:
HAVING Month=Month(NOW())
or, equivalently;
HAVING Month=Month(SYSDATE())
(edited)
To show only records from f.ex. March (month #3):
HAVING Month=3

Resources