I have written a SQL query but I am getting error as
Incorrect syntax near 'company_name'.
I am using SQL Server 2005.
My query:
SELECT TOP 1
MONTH(a.dt_of_leave) MONTH,
YEAR(a.dt_of_leave) YEAR
FROM
emp_mst a
WHERE
MONTH(a.dt_of_leave) >= MONTH(getdate()) - 1
AND YEAR(a.dt_of_leave) = CASE
WHEN MONTH(getdate()) = 1
THEN YEAR(getdate()) - 1
ELSE YEAR(getdate()) company_name 'COMPANY NAME',
Deputed_Company_Name 'DEPUTED COMPANY NAME' emp_card_no 'EMP CODE',
emp_name 'EMPLOYEE NAME',
LWP,
'' Remarks,
Adj_Days Gain_Loss_LOP_Days,
VAL_DAY LOP_Days_Desc,
MONTH,
YEAR
FROM XXACL_EMP_INFO_LWP_OTDAYS_HRS_V WHERE emp_type='C'
AND MONTH = '3'
AND YEAR = '2016'
AND emp_card_no IN(312,
1250,
362)
UPDATE
I have two working queries:
1st query
select top 1
month(a.dt_of_leave) month,
year(a.dt_of_leave) year
from
emp_mst a
where
month(a.dt_of_leave) >= month(getdate())-1
and year(a.dt_of_leave) = case
when month(getdate()) = 1
then year(getdate()) - 1
else year(getdate())
end
and emp_card_no IN (312, 1250, 362)
order by
emp_name
2nd query:
select
company_name 'COMPANY NAME',
Deputed_Company_Name 'DEPUTED COMPANY NAME',
emp_card_no 'EMP CODE',
emp_name 'EMPLOYEE NAME',
LWP, '' Remarks,
Adj_Days Gain_Loss_LOP_Days,
VAL_DAY LOP_Days_Desc, month, year
from
XXACL_EMP_INFO_LWP_OTDAYS_HRS_V
where
emp_type = 'C'
and month = '3' and year = '2015'
and emp_card_no in (312, 1250, 362)
What I want is in second query, I want to add month and year which i get from first query..
I need to merge that in second query
Try something like this - it will use the three emp_card_no given in the outer WHERE clause, and get their most recent month/year entry:
; WITH MonthAndYear AS
(
SELECT
MONTH(a.dt_of_leave) month,
YEAR(a.dt_of_leave) year,
emp_card_no,
RowNum = ROW_NUMBER() OVER (PARTITION BY emp_card_no ORDER BY dt_of_leave DESC)
FROM
emp_mst a
WHERE
MONTH(a.dt_of_leave) >= MONTH(GETDATE()) - 1
AND YEAR(a.dt_of_leave) = CASE
WHEN MONTH(GETDATE()) = 1
THEN YEAR(GETDATE()) - 1
ELSE YEAR(GETDATE())
END
)
SELECT
x.company_name 'COMPANY NAME',
x.Deputed_Company_Name 'DEPUTED COMPANY NAME',
x.emp_card_no 'EMP CODE',
x.emp_name 'EMPLOYEE NAME',
x.LWP, '' Remarks,
x.Adj_Days Gain_Loss_LOP_Days,
x.VAL_DAY LOP_Days_Desc,
x.month, x.year
FROM
XXACL_EMP_INFO_LWP_OTDAYS_HRS_V x
INNER JOIN
MonthAndYear my ON x.emp_card_no = my.emp_card_no
AND x.Month = my.Month AND x.Year = my.Year
AND my.RowNum = 1
WHERE
x.emp_type = 'C'
AND x.emp_card_no IN (312, 1250, 362);
I hope that's what you're looking for ! If not - please share table structure, sample data, expected output etc.
Related
I have an SQL statement that calculates how many days late our vendors pay for invoices. It only includes weekdays and it works perfectly. My customer is now asking if I can have an average of those days late per vendor. Here is my code that works:
DATEDIFF(dd, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE))
-(DATEDIFF(wk, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) * 2)
-(CASE WHEN DATENAME(dw, PURCHTABLE.CONFIRMEDDLV) = 'Sunday'
THEN 1
ELSE 0
END)
-(CASE WHEN DATENAME(dw, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) = 'Saturday'
THEN 1
ELSE 0
END) AS 'DAYS LATE'
If I try to put this in an AVG(), but it tells me I cannot perform an aggregate function on an aggregate function.
UPDATE:
This is my original SQL:
SELECT
PURCHTABLE.PURCHNAME AS 'VENDOR NAME',
PURCHTABLE.ORDERACCOUNT AS 'VENDOR NUMBER',
COUNT(DISTINCT PURCHTABLE.PURCHID) AS 'PURCHASE ORDER',
COUNT(PURCHLINE.LINENUMBER) AS 'NUMBER OF LINES',
SUM(PURCHLINE.LINEAMOUNT) AS 'PO PRICE TOTAL',
DATEDIFF(dd, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE))-(DATEDIFF(wk, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) * 2)-(CASE WHEN DATENAME(dw, PURCHTABLE.CONFIRMEDDLV) = 'Sunday' THEN 1 ELSE 0 END)-(CASE WHEN DATENAME(dw, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) = 'Saturday' THEN 1 ELSE 0 END) AS 'DAYS LATE'
FROM
PURCHTABLE
JOIN
PURCHLINE ON PURCHLINE.PURCHID = PURCHTABLE.PURCHID
JOIN
VENDPACKINGSLIPJOUR ON VENDPACKINGSLIPJOUR.PURCHID = PURCHTABLE.PURCHID
WHERE
PURCHTABLE.DELIVERYDATE >= '2017-01-01'
AND
PURCHTABLE.DELIVERYDATE <= '2017-01-20'
AND
PURCHTABLE.ORDERACCOUNT = 'VN03526'
GROUP BY
PURCHTABLE.PURCHNAME,
PURCHTABLE.ORDERACCOUNT,
PURCHTABLE.DELIVERYDATE,
PURCHTABLE.CONFIRMEDDLV
So I don't quite understand how I change that to what you are saying.....I'm tried this but it's not working.
SELECT
PURCHTABLE.PURCHNAME AS 'VENDOR NAME',
PURCHTABLE.ORDERACCOUNT AS 'VENDOR NUMBER'
FROM
(SELECT
PURCHTABLE.PURCHNAME AS 'VENDOR NAME',
PURCHTABLE.ORDERACCOUNT AS 'VENDOR NUMBER',
COUNT(DISTINCT PURCHTABLE.PURCHID) AS 'PURCHASE ORDER',
COUNT(PURCHLINE.LINENUMBER) AS 'NUMBER OF LINES',
SUM(PURCHLINE.LINEAMOUNT) AS 'PO PRICE TOTAL',
DATEDIFF(dd, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE))-(DATEDIFF(wk, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) * 2)-(CASE WHEN DATENAME(dw, PURCHTABLE.CONFIRMEDDLV) = 'Sunday' THEN 1 ELSE 0 END)-(CASE WHEN DATENAME(dw, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) = 'Saturday' THEN 1 ELSE 0 END) AS 'DAYS LATE'
FROM
PURCHTABLE
JOIN
PURCHLINE ON PURCHLINE.PURCHID = PURCHTABLE.PURCHID
JOIN
VENDPACKINGSLIPJOUR ON VENDPACKINGSLIPJOUR.PURCHID = PURCHTABLE.PURCHID
WHERE
PURCHTABLE.DELIVERYDATE >= '2017-01-01'
AND
PURCHTABLE.DELIVERYDATE <= '2017-01-20'
AND
PURCHTABLE.ORDERACCOUNT = 'VN03526') A
GROUP BY
PURCHTABLE.PURCHNAME,
PURCHTABLE.ORDERACCOUNT,
PURCHTABLE.DELIVERYDATE,
PURCHTABLE.CONFIRMEDDLV
The code you have at the moment will be part of a larger query, such as:
select VendorID
,VendorName
...
...
,<Your Days Late Code> as DaysLate
,InvoiceAmount
...
from tables
group by VendorID
,VendorName
all you need to do to average over all of this is pick the other columns you want to do the average by and wrap the whole thing in another select statement:
select VendorID
,VendorName
,avg(DaysLate) as AverageDaysLate
,sum(InvoiceAmount) as TotalInvoiceAmount
from(
select VendorID
,VendorName
...
...
,<Your Days Late Code> as DaysLate
,InvoiceAmount
...
from tables
group by VendorID
,VendorName
) a
group by VendorID
,VendorName
I have the following table for student's fee payments
[fee_id] INT
[user_id] INT
[payment] DECIMAL (18, 2)
[date] DATETIME
[fee_remaining] DECIMAL (18, 2)
[year] INT
[payment_method] NVARCHAR (50)
[fee_required] DECIMAL (18, 2)
This is my current query to display the number of students who have either paid, yet to pay or have partially paid their fees for the year
SELECT DISTINCT
(SELECT COUNT(*) AS Expr1
FROM fee_payments
WHERE (fee_remaining = 0)
AND (YEAR = #year)) AS Fully_Paid,
(SELECT COUNT(*) AS Expr1
FROM fee_payments
WHERE (fee_remaining = fee_required)
AND (YEAR = #year)) AS Unpaid,
(SELECT COUNT(*) AS Expr1
FROM fee_payments
WHERE (fee_remaining > 0)
AND (YEAR = #year)
AND (fee_remaining <> fee_required)) AS Partially_Paid
FROM fee_payments AS fee_payments_1
This is my output
Fully_Paid | Unpaid | Partially_Paid
-------------------------------------
8 | 1 | 5
Is it at all possible to have my output displayed as follows?
Status | Total
----------------------------
Fully Paid | 8
Unpaid | 1
Partially Paid | 5
Any help would be greatly appreciated
Use a case expression to assign the required status to each row and group by the calculated column.
select status, count(*) as total
from (
SELECT
case when fee_remaining = 0 then 'fully_paid'
when fee_remaining <> fee_required then 'partially_paid'
when fee_remaining = fee_required then 'unpaid'
end as status
FROM fee_payments
WHERE YEAR = #year) t
group by status
Also note this assumes fee_remaining and fee_required are non null values. If they can be null, use coalesce to handle them when comparing.
So without completely restructuring your query into something more efficient like kvp's answer, you could UNION each of the results instead of using them each as a sub-query:
SELECT 'Fully Paid' AS Status, COUNT(*) AS Total
FROM fee_payments
WHERE (fee_remaining = 0) AND (YEAR = #year)
UNION
SELECT 'Unpaid', COUNT(*)
FROM fee_payments
WHERE (fee_remaining = fee_required) AND (YEAR = #year)
UNION
SELECT 'Partially Paid', COUNT(*)
FROM fee_payments
WHERE (fee_remaining > 0) AND (YEAR = #year) AND (fee_remaining <> fee_required)
Your code appears to have more than one row per year. It seems like the last row would be the most informative, so I'm thinking something like this:
select sum(case when fee_remaining = 0 then 1 else 0 end) as FullyPaid,
sum(case when fee_remaining < fee_required then 1 else 0 end) as PartiallyPaid,
sum(case when fee_remaining = fee_required then 1 else 0 end) as Unpaid
from (select fp.*,
row_number() over (partition by user_id order by date desc) as seqnum
from fee_payments fp
where YEAR = #year
) fp
where seqnum = 1;
SELECT 'Fully Paid' as Status, COUNT(*) AS Total
FROM fee_payments
GROUP BY year
WHERE fee_remaining = 0
AND YEAR = #year
UNION ALL
SELECT 'Unpaid' as Status, COUNT(*) AS Total
FROM fee_payments
GROUP BY year
WHERE fee_remaining = fee_required
AND YEAR = #year
UNION ALL
SELECT 'Partially Paid' as Status, COUNT(*) AS Total
FROM fee_payments
GROUP BY year
WHERE fee_remaining > 0
AND YEAR = #year
AND fee_remaining <> fee_required
I want to exclude the weekend and the holiday from my table:
for example in this picture I would like to exclude the date 19.01. and 10.01 from my table or it should show only 0 in 10.01.2016.
this is my code:
SELECT *
FROM (
Select intervaldate as Datum, tsystem.Name as Name,
SUM(case when Name = 'Maschine 1' then Units else 0 end) as Maschine1,
Sum(case when Name = 'Maschine 2' then Units else 0 end) as Maschine2,
Sum(case when Name = 'Maschine 3' then Units else 0 end) as Maschine3,
from Count inner join tsystem ON Count.systemid = tsystem.id
where IntervalDate BETWEEN #StartDateTime AND #EndDateTime
and tsystem.Name in ('M101','M102','M103','M104','M105','M107','M109','M110', 'M111', 'M113', 'M114', 'M115')
group by intervaldate, tsystem.Name
) as s
I think the best approach is create a table in your database and store all weekend and holidays dates then use that table to filter your query.
Something like this:
SELECT *
FROM (
Select intervaldate as Datum, tsystem.Name as Name,
SUM(case when Name = 'Maschine 1' then Units else 0 end) as Maschine1,
Sum(case when Name = 'Maschine 2' then Units else 0 end) as Maschine2,
Sum(case when Name = 'Maschine 3' then Units else 0 end) as Maschine3,
from Count inner join tsystem ON Count.systemid = tsystem.id
where IntervalDate BETWEEN #StartDateTime AND #EndDateTime
and IntervalDate NOT IN (select WeekendOrHolidayDate from MyWeekendAndHolidayTable)
and tsystem.Name in ('M101','M102','M103','M104','M105','M107','M109','M110', 'M111', 'M113', 'M114', 'M115')
group by intervaldate, tsystem.Name
) as s
The below query will exclude weekdays only. There is no way to produce holidays from SQL if you want to exclude also holidays you have to store it somewhere in your database.
SELECT *
FROM (
Select intervaldate as Datum, tsystem.Name as Name,
SUM(case when Name = 'Maschine 1' then Units else 0 end) as Maschine1,
Sum(case when Name = 'Maschine 2' then Units else 0 end) as Maschine2,
Sum(case when Name = 'Maschine 3' then Units else 0 end) as Maschine3,
from Count inner join tsystem ON Count.systemid = tsystem.id
where IntervalDate BETWEEN #StartDateTime AND #EndDateTime
and ((DATEPART(dw, IntervalDate) + ##DATEFIRST) % 7) NOT IN (0, 1)
and tsystem.Name in ('M101','M102','M103','M104','M105','M107','M109','M110', 'M111', 'M113', 'M114', 'M115')
group by intervaldate, tsystem.Name
) as s
Let me know if this helps you.
For excluding weekend...you can use date function and IIF condition. If week number is 7 or 1 then exclude in report...You can do this by right click on report properties and choose filter..
Right click the row group in your tablix and select Row Visibility. In the Change display options, select Show or hide based on an expression. In the expression, this should work:
=iif(CDate(Fields!Date.Value).DayOfWeek = DayOfWeek.Saturday, true, iif(CDate(Fields!Date.Value).DayOfWeek = DayOfWeek.Sunday, true, false))
If there's a ton of data, for performance reasons I'd recommend trimming these rows on the database side.
Hi have query like this now i want to append value in query so tran_date is in Date time format in databases: so consider these two query
query 1:: i have to append value in date format but it not working ..how to pass year and month in date type::
select TRAN_DATE,
trunc(nvl(SUM(SALES_VALUE), 0) + nvl(sum(total_sales), 0) -
nvl(sum(net_sales), 0) + nvl(sum(discount), 0)) Sale
from OUTLET_PAYMODE_REPORT_FACT A, OUTLET_DETAILS B
WHERE A.OUTLET_ID = B.OUTLET_ID
and SALES_VALUE > 0
and to_date(TRAN_DATE, 'yyyy') = '2013'
AND to_date(TRAN_DATE, 'MON') = 'APR'
OR to_date(TRAN_DATE, 'yyyy') = '2013'
AND to_date(TRAN_DATE, 'MON') = 'MAR'
GROUP BY TRAN_DATE
query 2: its work but it is string format
select TRAN_DATE,
trunc(nvl(SUM(SALES_VALUE), 0) + nvl(sum(total_sales), 0) -
nvl(sum(net_sales), 0) + nvl(sum(discount), 0)) Sale
from OUTLET_PAYMODE_REPORT_FACT A, OUTLET_DETAILS B
WHERE A.OUTLET_ID = B.OUTLET_ID
and SALES_VALUE > 0
and (to_char(TRAN_DATE, 'yyyy') = '2013' AND
to_char(TRAN_DATE, 'MON') = 'APR')
OR (to_char(TRAN_DATE, 'yyyy') = '2013' AND
to_char(TRAN_DATE, 'MON') = 'MAR')
GROUP BY TRAN_DATE
One of options is to use BETWEEN condition with DATETIME datatype columns:
select TRAN_DATE,
trunc(nvl(SUM(SALES_VALUE), 0) + nvl(sum(total_sales), 0) -
nvl(sum(net_sales), 0) + nvl(sum(discount), 0)) Sale
from OUTLET_PAYMODE_REPORT_FACT A, OUTLET_DETAILS B
WHERE A.OUTLET_ID = B.OUTLET_ID
and SALES_VALUE > 0
and TRAN_DATE between to_date('01.03.2013', 'dd.mm.yyyy') and
to_date('30.04.2013', 'dd.mm.yyyy')
GROUP BY TRAN_DATE;
I am trying to count instances of a status by current day and current week, grouped by town.
(The table has just 3 columns: Town, status, status_date)
SELECT
MAX(dbo.Clients.Town) AS Town,
CASE
WHEN MAX(datepart(wk, status_date)) = DATEPART(wk, getdate()) THEN COUNT(Town)
ELSE 0
END AS wkTotal,
CASE
WHEN MAX(CONVERT(date, status_date, 106)) = CONVERT(date, getdate(), 106) THEN COUNT(Town)
ELSE 0
END AS dayTotal
FROM
dbo.Clients
WHERE
dbo.Clients.Status LIKE 'Status 1%'
AND MONTH(GETDATE()) = MONTH(dbo.Clients.Status_date)
AND YEAR(GETDATE())= YEAR(dbo.Clients.Status_date)
GROUP BY
dbo.Clients.Town
ORDER BY
dbo.Clients.Town
This code just returns a month count for both day total and week total columns
Hope you can help.
I surgest you do this:
SELECT dbo.Clients.Town AS Town,
count(*) AS wkTotal,
sum(CASE WHEN datepart(dayofyear, status_date) = DATEPART(dayofyear, getdate()) THEN 1 ELSE 0 END) AS dayTotal
FROM dbo.Clients
WHERE dbo.Clients.Status LIKE 'Status 1%' AND
datepart(week, GETDATE()) = datepart(week, dbo.Clients.Status_date)
AND YEAR(GETDATE())= YEAR(dbo.Clients.Status_date)
GROUP BY dbo.Clients.Town
ORDER BY dbo.Clients.Town