Why name column in table repeats itself? - sql

hello i have been working on this query since many days and finally almost done with it except 1 problem.
It gives me this output
N ConductorName Denomination totaltransactions totalamount
1 NULL NULL 1882 41610.00
1 Imran 30.00 199 5970.00
2 NULL Imran total 199 5970.00
1 Shoaib 30.00 99 2970.00
2 NULL Shoaib total 99 2970.00
1 Umair 10.00 792 7920.00
2 Umair 15.00 396 5940.00
3 Umair 30.00 99 2970.00
4 Umair 40.00 99 3960.00
5 Umair 60.00 198 11880.00
6 NULL Umair total 1584 32670.00
it fine but i want to eliminate name repetition in ConductorName column i.e.
Expected:
N ConductorName Denomination totaltransactions totalamount
1 NULL NULL 1882 41610.00
1 Imran 30.00 199 5970.00
2 NULL Imran total 199 5970.00
1 Shoaib 30.00 99 2970.00
2 NULL Shoaib total 99 2970.00
1 Umair 10.00 792 7920.00
2 NULL 15.00 396 5940.00
3 NULL 30.00 99 2970.00
4 NULL 40.00 99 3960.00
5 NULL 60.00 198 11880.00
6 NULL Umair total 1584 32670.00
so every name 1 time but data intact.
SP:
ALTER PROCEDURE [dbo].[ReportConductorPerformance]
#FromDate DATE,
#ToDate DATE
AS
BEGIN
SELECT ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) 'N',CASE WHEN isnull(CAST(T .amount AS varchar(30)), c.name + ' total') LIKE '%total%' THEN NULL ELSE c.name END AS ConductorName,
ISNULL(CAST(T.Amount AS varchar(30)), c.Name + ' total') AS Denomination, COUNT(*) AS totaltransactions, SUM(T.Amount) AS totalamount
FROM dbo.Tickets AS T INNER JOIN
Transport.Conductors AS c ON c.ConductorID = T.Conductor_ID
WHERE CONVERT(DATE,ServerDateTime) BETWEEN #FromDate and #ToDate
GROUP BY c.Name, T.Amount WITH ROLLUP
END

While I wouldn't recommend handling this in the database, you could utilize the case statement to achieve your results since you're already using row_number:
SELECT N,
case when N = 1 then ConductorName else NULL end ConductorName,
Denomination,
totaltransactions,
totalamount
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) 'N',
CASE WHEN isnull(CAST(T.amount AS varchar(30)), c.name + ' total') LIKE '%total%'
THEN NULL
ELSE c.name
END AS ConductorName,
ISNULL(CAST(T.Amount AS varchar(30)), c.Name + ' total') AS Denomination,
COUNT(*) AS totaltransactions,
SUM(T.Amount) AS totalamount
FROM dbo.Tickets AS T INNER JOIN
Transport.Conductors AS c ON c.ConductorID = T.Conductor_ID
WHERE CONVERT(DATE,ServerDateTime) BETWEEN #FromDate and #ToDate
GROUP BY c.Name, T.Amount WITH ROLLUP
) T

In this scenario you can use the existing CASE statement with a simplified condition only keeping the name for the first row within your partition. Also, if you leave out the 'ELSE' the value will be NULL by default, a slight simplification.
Another slight simplification is to use SQL Server's grouping method to detect your extra rows instead of watching for values that are NULL.
SELECT
ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) 'N',
CASE
WHEN T.amount IS NOT NULL AND ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) = 1 THEN c.name
END AS ConductorName,
CASE
WHEN grouping(T.Amount) = 0 THEN CONVERT(VARCHAR(30), T.Amount)
ELSE c.Name + ' total'
END AS totaltransactions,
SUM(T.Amount) AS totalamount
FROM dbo.Tickets AS T
INNER JOIN Transport.Conductors AS c ON c.ConductorID = T.Conductor_ID
WHERE CONVERT(DATE,ServerDateTime) BETWEEN #FromDate and #ToDate
GROUP BY c.Name, T.Amount WITH ROLLUP;

Related

SQL Server - SUM and comma-separated values using GROUP BY clause

I have 2 tables:
NDEvent:
EventId EndTime
33 2020-10-23 15:00:00.000
33 2020-10-23 15:00:00.000
35 2020-10-21 03:30:00.000
35 2020-10-24 15:00:00.000
35 2020-10-25 15:00:00.000
34 2020-10-23 15:00:00.000
EventAppointment:
Id DocId EventId Amount
1 7647 34 10.00
2 7647 34 10.00
3 28531 33 20.00
4 7647 35 20.00
5 7647 35 100.00
6 7647 35 200.00
And I want result to be like this:
DocId EventId Amount Id
7647 34 20.00 1,2
28531 33 20.00 3
7647 35 320.00 4,5,6
What I have tried is:
select e.Amount,e.DoctorId,e.EventId,
Id= STUFF(
(SELECT DISTINCT ',' + CAST(e.Id as nvarchar(max))
from NDEvent nd
inner join EventAppointment e on nd.Id = e.EventId
where
GETDATE() > nd.EndTime
GROUP BY
e.Amount,e.DoctorId,e.EventId,e.Id
FOR XML PATH(''))
, 1, 1, ''
)
from NDEvent nd
inner join EventAppointment e on nd.Id = e.EventId
where
GETDATE() > nd.EndTime
GROUP BY
e.Amount,e.DoctorId,e.EventId
But it is not giving expected result.
Could anyone help with this query? Or point me to a right direction? Thank you.
It doesn't look like yo need to NDEvent table here at all (though I include it in the sample data). Just SUM and STRING_AGG against EventAppointment:
USE Sandbox
GO
WITH NDEvent AS(
SELECT *
FROM (VALUES(33,CONVERT(datetime,'2020-10-23T15:00:00.000')),
(33,CONVERT(datetime,'2020-10-23T15:00:00.000')),
(35,CONVERT(datetime,'2020-10-21T03:30:00.000')),
(35,CONVERT(datetime,'2020-10-24T15:00:00.000')),
(35,CONVERT(datetime,'2020-10-25T15:00:00.000')),
(34,CONVERT(datetime,'2020-10-23T15:00:00.000')))V(EventID,EndTime)),
EventAppointment AS(
SELECT *
FROM (VALUES(1,7647 ,34,10.00),
(2,7647 ,34,10.00),
(3,28531,33,20.00),
(4,7647 ,35,20.00),
(5,7647 ,35,100.00),
(6,7647 ,35,200.00))V(Id,DocId, EventID, Amount))
SELECT DocID,
EventID,
SUM(Amount) AS Amount,
STRING_AGG(Id,',') WITHIN GROUP (ORDER BY Id) AS IDs
FROM EventAppointment EA
GROUP BY DocId,
EventID;
Can be used in other data.
WITH Table1 AS(
SELECT EventId FROM NDEvent
GROUP BY EventId
),
Table2 AS(
SELECT e.DocId,e.EventId,e.Amount,
STUFF((
SELECT ',' + CAST(ee.Id as nvarchar)
FROM EventAppointment ee
where ee.EventId = e.EventId
GROUP BY ee.EventId,ee.Id
FOR XML PATH('')), 1, 1, '') AS Id
FROM Table1 t
LEFT OUTER JOIN EventAppointment e ON t.EventId = e.EventId
)
SELECT DocId,EventId,SUM(Amount) AS Amount,Id FROM Table2
GROUP BY DocId,EventId,Id

Data according to time

I have table1 in this data is
ID Name StartDate EndDate
1 Paris 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
2 UK 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
3 France 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
and sp is
ALTER procedure [dbo].[spdata]
#fromdate datetime,
#todate datetime,
#Region varchar(50)
as
Select (Select Sum(Convert(int,SF)) from RVU inner dbo.VI vh on RVU.FID = vh.FID WHERE vh.No = Q.No and ID in (
Select ID from RU WHERE CAST(StartDate as date)>= CAST(#fromdate as date) and CAST(EndDate as date)<= CAST(#todate as date)
)) as SF
from (
Select
S.Name,
S.No,
SUM(Case when s.Vme='Car' then total else 0 end) as CAR,
SUM(Case when s.Vme='Tin' then total else 0 end) as Tin,
SUM(Case when s.Vme='Cake' then total else 0 end) as Cake,
SUM(Case when s.Vme='Flow' then total else 0 end) as Flow,
SUM(Case when s.Vme='Unit' then total else 0 end) as Unit,
SUM(total) total ,
MAX(S.Speed) Speed
from (
Select vh.Name as Name,vh.No as No,VV.Vame,count(VV.Vme) as total, RV.SF as MA,
RV.Speed from VVU VV inner join RVU RV on VV.MID=RV.ID inner join RU RU on RV.ID=RU.ID
left join dbo.VI vh on RV.FID = vh.FID WHERE CAST(RU.StartDate as date)>= CAST(#fromdate as date) and CAST(RU.EndDate as date)<= CAST(#todate as date) and
RU.Name_C= #Name_C AND Vme <> '' Group By vh.Name, vh.No, VV.Vme, RV.SF,
RV.Speed ) S GROUP BY s.RegNo, s.Name) Q
from that sp when i enter parameters DATA IS
[spdata] '2016-07-01 00:00:00.000', '2016-07-31 23:59:59.000', 'pARIS'
Name No CAR Tin Cake Flow Unit total Speed SF
John 412 0 0 12 0 5 17 82 60
Mike 48 2 1 5 1 3 9 160 464
ACNme 438 0 1 5 2 3 11 10 264
XYZ 248 0 1 5 3 3 12 60 244
now i want when i change time '2016-07-01 00:00:00.000', '2016-07-31 23:59:59.000',
like this
'2016-07-01 02:02:00.000', '2016-07-31 12:59:59.000',
then records also reflect on this time means according to date plus time data will be display
Don't cast your StartDate , EndDate , #fromdate , #todate as Date.
`Alter procedure [dbo].[spdata]
#fromdate datetime,
#todate datetime,
#Region varchar(50)
as
Select (Select Sum(Convert(int,SF)) from RVU inner dbo.VI vh on RVU.FID = vh.FID WHERE vh.No = Q.No and ID in (
Select ID from RU WHERE StartDate >= #fromdate and EndDate <=#todate
)) as SF
from (
Select
S.Name,
S.No,
SUM(Case when s.Vme='Car' then total else 0 end) as CAR,
SUM(Case when s.Vme='Tin' then total else 0 end) as Tin,
SUM(Case when s.Vme='Cake' then total else 0 end) as Cake,
SUM(Case when s.Vme='Flow' then total else 0 end) as Flow,
SUM(Case when s.Vme='Unit' then total else 0 end) as Unit,
SUM(total) total ,
MAX(S.Speed) Speed
from (
Select vh.Name as Name,vh.No as No,VV.Vame,count(VV.Vme) as total, RV.SF as MA,
RV.Speed from VVU VV inner join RVU RV on VV.MID=RV.ID inner join RU RU on RV.ID=RU.ID
left join dbo.VI vh on RV.FID = vh.FID WHERE RU.StartDate >= #fromdate and RU.EndDate <= #todate and
RU.Name_C= #Name_C AND Vme <> '' Group By vh.Name, vh.No, VV.Vme, RV.SF,
RV.Speed
) S GROUP BY s.RegNo, s.Name) Q`

Statement of account from transactions SQL

I have a list of transactions in a table for a user which records, the UserID, DateTime, TransactionType and Value. TransactionID is the Primary Key auto increment 1. The TransactionType defines a Deposit (1) or Withdrawal (2) so all values are positive in the table. I am trying to create a statement of account with a running total.
TransactionID UserID DateTime TransactionTypeID Value
1 3112 01-04-2016 12:00 1 5.00
3 3112 01-04-2016 13:00 2 2.00
5 3112 01-04-2016 13:25 2 1.00
8 3112 02-04-2016 12:00 1 10.00
9 3112 02-04-2016 12:35 2 4.00
Basically I want to create a running statement of account query with a Total value to create:
DateTime TransactionTypeID Deposit Withdrawal Balance
01-04-2016 12:00 1 5.00 5.00
01-04-2016 13:00 2 2.00 3.00
01-04-2016 13:25 2 1.00 2.00
02-04-2016 12:00 1 10.00 12.00
02-04-2016 12:35 2 4.00 8.00
I have tried using OUTER APPLY to select the previous transaction but with no prevail in a single query. Any assistance would be appreciated
SELECT
[UserID], [DateTime],
T.[Value] *
(CASE
WHEN [TransactionTypeID] IN (1, -- deposit
2 -- withdrawal
)
THEN -1
ELSE 1
END),
T2.Value AS PrevValue
FROM
[Transaction] T
OUTER APPLY
(SELECT TOP 1 T2.[Value]
FROM [Transaction] T2
WHERE UserID = 3112
AND T2.[TransactionID] > T.TransactionID
ORDER BY T2.TransactionID) AS T2
WHERE
T.[UserID] = 3112
ORDER BY
T.[TransactionID] DESC
the query you're asking for should look something like this..
SQL 2005
SELECT [DateTime],
[TransactionID],
[Deposit] = CASE WHEN TransactionTypeID = 1 THEN [Value] END,
[Withdrawal] = CASE WHEN TransactionTypeID = 2 THEN -[Value] END,
[Balance] = CASE TransactionTypeID WHEN 1 THEN [Value]
WHEN 2 THEN -[Value] END + ISNULL([PrevValue], 0)
FROM [Transaction] t1
OUTER APPLY (SELECT SUM(CASE TransactionTypeID WHEN 1 THEN [Value]
WHEN 2 THEN -[Value] END) AS [PrevValue]
FROM [Transaction] t2
WHERE t1.UserID = t2.UserID AND t2.[DateTime] < t1.[DateTime]) ca
WHERE UserID = 3112
SQL 2008+
SELECT [DateTime],
[TransactionID],
[Deposit] = CASE WHEN TransactionTypeID = 1 THEN [Value] END,
[Withdrawal] = CASE WHEN TransactionTypeID = 2 THEN -[Value] END,
[Balance] = SUM(CASE TransactionTypeID WHEN 1 THEN [Value]
WHEN 2 THEN -[Value] END)
OVER (ORDER BY [DateTime])
FROM [Transaction]
WHERE UserID = 3112
I Have found a SQL Server 2012 solution. If you are running an older version please check alternatives.
It uses SUM OVER..
select [TransactionID],
[DateTime],
( CASE WHEN [TransactionTypeID] IN (
1, -- deposits
2 -- withdrawals
)
THEN -[Value]
ELSE [Value]
END
),
sum(( CASE WHEN [TransactionTypeID] IN (
1, -- deposits
2 -- withdrawals
)
THEN -[Value]
ELSE [Value]
END
)) over(order by [DateTime] rows unbounded preceding) as runningtotal
from [Transaction]
WHERE UserID = 3112

select group by column optionally in rows

I need to calculate employee salaries.
I have a table and two views which holds data i need to perform a query, here are the tables
Employees_View
--------
ID Name PayRate PayUnit Commission
1 James 10 C 0
2 Mike 10000 S 0
3 Jude 20000 SC 5
4 Clara 8 C 0
When PayUnit is C (Commission) then PayRate is in Percent, this is percent of the total sale by this employee, whereas the Commission field is commission percent on total sales and its only for SC employees
Jobs
ID Created
1 2016-01-21 10:56:05
2 2016-01-21 10:56:05
3 2016-01-21 10:56:05
4 2016-01-21 10:56:05
5 2016-01-21 12:11:59
6 2016-01-25 08:03:07
7 2015-11-01 22:55:22
Jobs_Item_View
Job_ID Amount Emp_ID
1 135 4
1 500 2
3 1500 2
3 250 4
4 1000 2
5 500 4
6 500 4
7 500 1
PayUnits
Code Name
S Salary
C Commission
SC Salary plus Commission
Here is what i tried
SELECT
ev.PayRate,
ev.name AS Employee,
CASE ev.PayUnitCode WHEN 'C' THEN
SUM(jiv.Amount) - (SUM(jiv.Amount) * (ev.PayRate / 100))
WHEN 'SC' THEN
ev.payrate + SUM(jiv.Amount) - (SUM(jiv.Amount) * (ev.Commission / 100))
ELSE ev.payrate
END AS pay,
LEFT(DATENAME(month, j.Created), 3) + '-' + CAST(YEAR(j.Created) AS NVARCHAR) AS Month,
jiv.Emp_ID,
pu.Name AS PayUnit,
ev.Code, ev.Commission
FROM
dbo.Employees_View AS ev LEFT OUTER JOIN
dbo.Job_Items_View AS jiv ON jiv.Emp_ID = ev.ID LEFT OUTER JOIN
dbo.Jobs AS j ON j.ID = jiv.Job_ID LEFT OUTER JOIN
dbo.PayUnits AS pu ON pu.Code = ev.PayUnitCode
GROUP BY jiv.Emp_ID,
pu.Name,
ev.PayUnitCode,
ev.PayRate, ev.name,
LEFT(DATENAME(month, j.Created), 3) + '-' + CAST(YEAR(j.Created) AS NVARCHAR),
ev.Code, ev.Commission
This is what i got
Result
PayRate Employee pay Month Emp_ID PayUnit Commission
20000 Jude NULL NULL NULL Salary plus Commission 5.00
10 James 900 Nov-2015 1 Commission 0.00
8 Clara 2760 Jan-2016 4 Commission 0.00
10000 Mike 10000 Jan-2016 2 Salary 0.00
Expected Output
Result
PayRate Employee pay Month Emp_ID PayUnit Commission
20000 Jude 20241.75 Jan-2016 3 Salary plus Commission 5.00
10 James 900 Nov-2015 1 Commission 0.00
8 Clara 2760 Jan-2016 4 Commission 0.00
10000 Mike 10000 Jan-2016 2 Salary 0.00
the Pay for the SC employee isn't correct. it is suppose to be Salary (20000) plus 5% or total sales (4835) which is 241.75 - 20,241.75
The reason for the nulls is that one of the employees did not contribute to any jobs, so SUM(jiv.Amount) will always be null for them and any calculations involving that expression will also result in null. You can fix by doing ISNULL(SUM(jiv.Amount), 0). Similarly for the dates, they are also driven by the jobs data, but if an employee wasn't involved in any jobs they will be null also. ISNULL() could be used for these as well.
I've broken the problem down by using Common Table Expressions:
DECLARE #startDateTime DATETIME = '2016-01-01 00:00:00'
DECLARE #endDateTime DATETIME = '2016-01-31 23:59:59'
;WITH sales AS
(
SELECT
ev.ID,
ISNULL(SUM(jiv.Amount), 0) AS TotalSales,
MONTH(j.Created) AS [Month],
YEAR(j.Created) AS [Year]
FROM Employees_View AS ev
LEFT JOIN Job_Items_View AS jiv ON jiv.Emp_ID = ev.ID
LEFT JOIN Jobs AS j ON j.ID = jiv.Job_ID
WHERE j.Created BETWEEN #startDateTime AND #endDateTime
GROUP BY
ev.ID,
MONTH(j.Created),
YEAR(j.Created)
),
commissions AS
(
SELECT
s.ID,
CASE ev.PayUnitCode
WHEN 'C' THEN s.TotalSales * (ev.PayRate / 100)
WHEN 'SC' THEN (SELECT SUM(Amount) FROM Job_Items_View) * (ev.Commission / 100)
ELSE 0
END AS TotalCommission
FROM sales AS s
JOIN Employees_View AS ev ON ev.ID = s.ID
),
salaries AS
(
SELECT
ID,
CASE PayUnitCode
WHEN 'C' THEN 0
ELSE PayRate
END AS Salary
FROM Employees_View
),
totals AS
(
SELECT
salaries.ID,
ISNULL(sales.Month, MONTH(#startDateTime)) AS [Month],
ISNULL(sales.Year, YEAR(#startDateTime)) AS [Year],
ISNULL(sales.TotalSales, 0) AS TotalSales,
salaries.Salary,
ISNULL(commissions.TotalCommission, 0) AS TotalCommission
FROM salaries
LEFT JOIN sales ON salaries.ID = sales.ID
LEFT JOIN commissions ON commissions.ID = sales.ID
)
SELECT
ev.PayRate,
ev.Name,
t.Salary + t.TotalCommission AS Pay,
LEFT(DATENAME(MONTH, DATEADD(MONTH , t.[Month], -1)), 3)
+ '-' + CAST(t.[Year] AS VARCHAR) AS [Month],
ev.ID AS Emp_ID,
pu.Name AS PayUnit,
ev.Commission
FROM totals AS t
JOIN Employees_View AS ev ON ev.ID = t.ID
JOIN PayUnits AS pu ON pu.Code = ev.PayUnitCode
Click here to see it in action and have a play on SQL Fiddle.

T-SQL NULL-Friendly Query

I have a table "tblSalesOrder" in Microsoft T-SQL with some sample records:
SalesOrderID OrderDate ItemID Quantity PromotionCode
====================================================================
1 2014-09-01 100 5 NULL
2 2014-09-01 120 10 ABC
3 2014-09-05 150 7 NULL
4 2014-09-08 200 15 NULL
I need to return NULL-friendly resultset for records which do not exist.
As an example, I want a monthly query for September 2014:
SELECT SalesOrderID, OrderDate, ItemID, Quantity, PromotionCode
FROM tblSalesOrder
WHERE OrderDate = BETWEEN '2014-09-01' AND '2014-09-30'
I need it to return at least 1 row for each day (i.e. 0 valued row, if the entry for that day is not available)
SalesOrderID OrderDate ItemID Quantity PromotionCode
====================================================================
1 2014-09-01 100 5 NULL
2 2014-09-01 120 10 ABC
0 2014-09-02 0 0 0
0 2014-09-03 0 0 0
0 2014-09-04 0 0 0
3 2014-09-05 150 7 NULL
0 2014-09-06 0 0 0
0 2014-09-07 0 0 0
4 2014-09-08 200 15 NULL
0 2014-09-09 0 0 0
...
...
...
0 2014-09-30 0 0 0
master..spt_values is a table in all microsoft sql databases containing 2506 rows, by cross joining, it will have 2506*2506 rows to calculate dates between from and to. Other tables can be used as well, this is just a table used to create the dates. A calendar table would be even easier to use.
The EXCEPT will remove all dates already in use. Then by combining the rows from tblSalesOrder and CTE with union all, empty days will be filled with the required hardcoded values:
DECLARE #from date = '2014-09-01'
DECLARE #to date = '2014-09-30'
;WITH CTE as
(
SELECT top (case when #to < #from then 0 else datediff(day, #from, #to) + 1 end)
dateadd(day, row_number() over (order by (select 1)) - 1, #from) OrderDate
FROM
master..spt_values t1
CROSS JOIN
master..spt_values t2
EXCEPT
SELECT
OrderDate
FROM
tblSalesOrder
)
SELECT
0 SalesOrderID, OrderDate, 0 ItemID, 0 Quantity, '0' PromotionCode
FROM
CTE
UNION ALL
SELECT
SalesOrderID, OrderDate, ItemID, Quantity, PromotionCode
FROM
tblSalesOrder
ORDER BY
OrderDate, SalesOrderId
You can join the a date parameter in an empty select and coalesce the values:
select coalesce(t.SalesOrderID, 0) SalesOrderID
, coalesce(t.OrderDate, d.OrderDate) OrderDate
, coalesce(t.ItemID, 0) ItemID
, coalesce(t.Quantity, 0) Quantity
, coalesce(t.PromotionCode, 0) PromotionCode
from (select #dateParameter OrderDate) d
left
outer
join ( SELECT SalesOrderID, OrderDate, ItemID, Quantity, PromotionCode
FROM tblSalesOrder
) t
on t.OrderDate = d.OrderDate
DECLARE #startDate date= '20140901'
,#endDate date = '20140930';
WITH Calendar as (
SELECT #startDate as OrderDate
UNION ALL
SELECT DATEADD(DAY, 1, OrderDate) as OrderDate
FROM Calendar
WHERE OrderDate < #endDate
)
SELECT coalesce(t.SalesOrderID, 0) SalesOrderID
, coalesce(t.OrderDate, Calendar.OrderDate) OrderDate
, coalesce(t.ItemID, 0) ItemID
, coalesce(t.Quantity, 0) Quantity
, CASE WHEN t.OrderDate IS NULL THEN '0' ELSE t.PromotionCode END as PromotionCode FROM Calendar
LEFT JOIN tblSalesOrder t ON Calendar.OrderDate = t.OrderDate
ORDER BY Calendar.OrderDate, t.SalesOrderID
OPTION (MAXRECURSION 0);