Case in where condition to calculate individual totals - mysql

select
Count(*)
from gl
join TRVMAINDATA msit
on gl.TRANSACTIONID = msit.CHARGETRANSACTIONID
where gl.CREATEDDATETIME >= DATEADD(MONTH,-2,getdate()) AND
datediff(DAY,gl.BUSINESSPROCESSDATE,gl.CREATEDDATETIME)>=4 AND
gl.MARKETCODE In('535','532','056','050','039','036','034','033','030','029','027','023','022','021','018','015','012','011','010','009','007','006','005','002','001' ) and DATEADD(MONTH,DATEDIFF(MONTH,0,gl.CREATEDDATETIME),0) = '2/1/2017 12:00:00 AM'
The above code gives the total for market code mentioned.
But i also want the market code for other code which doesn't belog here. for example
select
Count(*)
from gl
join TRVMAINDATA msit
on gl.TRANSACTIONID = msit.CHARGETRANSACTIONID
where gl.CREATEDDATETIME >= DATEADD(MONTH,-6,getdate()) AND
datediff(DAY,gl.BUSINESSPROCESSDATE,gl.CREATEDDATETIME)>=0
and
DATEADD(MONTH,DATEDIFF(MONTH,0,gl.CREATEDDATETIME),0) = '2/1/2017 12:00:00 AM'
AND
(case
when gl.MARKETCODE In('535','532','056','050','039','036','034','033','030','029','027','023','022','021','018','015','012','011','010','009','007','006','005','002','001') then 'Proprietary'
when gl.MARKETCODE='037' then 'US'
else 'partner'
end )
Is it possible to calculate totals of other market codes in one sql query or do i have to calculate individually?

I think you would like to do count with case when in select statement like this:
SELECT COUNT(CASE
WHEN gl.marketcode IN ( '535', '532', '056', '050',
'039', '036', '034', '033',
'030', '029', '027', '023',
'022', '021', '018', '015',
'012', '011', '010', '009',
'007', '006', '005', '002', '001' ) THEN 1
ELSE NULL
END) AS `Proprietary`,
COUNT(CASE
WHEN gl.marketcode = '037' THEN 1
ELSE NULL
END) AS `US`,
COUNT(CASE
WHEN gl.marketcode NOT IN ( '535', '532', '056', '050',
'039', '036', '034', '033',
'030', '029', '027', '023',
'022', '021', '018', '015',
'012', '011', '010', '009',
'007', '006', '005', '002',
'001', '037' ) THEN 1
ELSE NULL
END) AS `partner`
FROM gl
JOIN trvmaindata msit
ON gl.transactionid = msit.chargetransactionid
WHERE gl.createddatetime >= DATEADD(month, -2, GETDATE())
AND DATEDIFF(day, gl.businessprocessdate, gl.createddatetime) >= 4
AND DATEADD(month, DATEDIFF(month, 0, gl.createddatetime), 0) = '2/1/2017 12:00:00 AM'

Related

Explain me ways to understand this complex query

Can anyone help me to understand this big sql query. How do I break it down in small chunks to understand it ?
select t.Instrument as Instrument ,ClearingId as ClearingId,
ISNULL( PrevQty ,0) AS PrevQty,SettlePrice,
ISNULL(TodayBuyQty,0) as TodayBuyQty,
ISNULL( TodaySellQty ,0) AS TodaySellQty,
ISNULL(PrevQty +TodayBuyQty-TodaySellQty,0) as NetQty,
TodayBuyPrice, TodaySellPrice,LTP,PnL,Token
from
(
select Instrument,w.ClearingId as ClearingId,
ISNULL( PrevQty ,0) AS PrevQty,ISNULL(TodayBuyQty,0) as TodayBuyQty,
ISNULL( TodaySellQty ,0) AS TodaySellQty,
TodayAvgBuyPrice as TodayBuyPrice,TodayAvgSellPrice as TodaySellPrice,
LTP,PnL,w.Token
from
(
select Symbol as Instrument, ClearingId,
ISNULL(TodayBuyQty,0) as TodayBuyQty,
TodayAvgBuyPrice,
ISNULL( -TodaySellQty ,0) AS TodaySellQty,
TodayAvgSellPrice, NULL as LTP ,NULL as PnL ,
w.Token as Token
from
(
select Token, sum(Qty) as NetPositionQty, ClearingId,
sum(CASE WHEN Qty < 0 THEN Qty ELSE 0 END) as TodaySellQty,
sum(CASE WHEN Qty > 0 THEN Qty ELSE 0 END) as TodayBuyQty,
sum(CASE WHEN Qty < 0 THEN Qty * Price ELSE 0 END)
/
NULLIF(sum(CASE WHEN Qty < 0 THEN Qty ELSE 0 END), 0) as TodayAvgSellPrice,
sum(CASE WHEN Qty > 0 THEN Qty * Price ELSE 0 END)
/
NULLIF(sum(CASE WHEN Qty > 0 THEN Qty ELSE 0 END), 0) as TodayAvgBuyPrice
from
(
select m.Token,
(CASE WHEN ClearingId = 'SATP' THEN 'STRAITS' ELSE CASE WHEN ClearingId = 'BATP' THEN 'BPI' ELSE 'UOB' END END ) as ClearingId ,
Price/CAST(Multiplier AS float ) as Price,Qty
from
(
select Token , Exchange as ClearingId ,
LastTradePrice as Price ,
CASE WHEN Side = 'S' THEN -LastTradeQuantity ELSE LastTradeQuantity END as Qty
from Strategy_Orders
where ExchangeStatus in (9,10) )m
JOIN TokenMap t ON ( m.Token = t.Token)
UNION ALL
select m.Token, (CASE WHEN ClearingId = 'SATP' THEN 'STRAITS' ELSE CASE WHEN ClearingId = 'BATP' THEN 'BPI' ELSE 'UOB' END END ) as ClearingId ,
Price/CAST(Multiplier AS float ) as Price,
Qty
from
(
select Token , Exchange as ClearingId ,
LastTradePrice as Price ,
CASE WHEN Side = 'S' THEN -LastTradeQuantity ELSE LastTradeQuantity END as Qty
from Manual_Orders
where ExchangeStatus in (9,10) )m
JOIN TokenMap t ON ( m.Token = t.Token)
UNION ALL
select Token , ClearingId , TodayBuyPrice ,
TodayBuyQty as Qty
from EOD_Holdings
where CurrentDate =
( select top 1 CurrentDAte from EOD_Holdings
order by CurrentDAte desc
)
UNION ALL
select Token , ClearingId , TodaySellPrice ,
TodaySellQty as Qty
from EOD_Holdings
where CurrentDate = (
select top 1 CurrentDAte from EOD_Holdings
order by CurrentDAte desc
)
) x
group by Token,ClearingId) w
JOIN(select Token, Symbol from TokenMAp ) h on w.Token = h.Token
) w
FULL OUTER JOIN(
select Token, PrevQty , ClearingId
from EOD_Holdings
where CurrentDate = ( select top 1 CurrentDAte from EOD_Holdings order by CurrentDAte desc
)
) h
on w.Token = h.Token and w.ClearingId = h.ClearingId
)t
JOIN (
select * from LatestSettlePrices
) sp
on t.Instrument = sp.Instrument
You can break the query into chunks by looking at each subquery ("select ..." ) separately and running them to see the results. You need to start with the innermost queries that do not have other select statements in the "from" or "where" clause.
Also note that this query does not seem to be a clear, neither an optimal solution.
You would want to avoid using full outer joins and union all statements for the best performance.

SQL Get the total count of registered user in day by day

Can you help me to construct a query. The scenario is this, I want to get the total value of the registered users each day.
Select count(*)
from tableName
Where registered = true
Group by Date
Assuming that your registration timestamp is stored at created_at date-time field and table named say user:
SELECT created_at,COUNT(*) as `total registration` FROM `user` GROUP BY (DATE(`user`.`created_at`))
The former answers do neither cover the where part nor output the dayname.
This should do both and produce what you want:
create table #data (
reg_id int,
reg_email nvarchar(255),
reg_date datetimeoffset(7)
)
insert into #data(reg_id, reg_email, reg_date)
VALUES
(1, 'a', '2018-10-01'),
(2, 'b', '2018-10-01'),
(3, 'c', '2018-10-02'),
(4, 'd', '2018-10-03'),
(5, 'e', '2018-10-01'),
(6, 'f', '2018-10-02'),
(7, 'g', '2018-10-04'),
(8, 'h', '2018-10-05'),
(9, 'i', '2018-10-05'),
(10, 'j', '2018-10-06')
SELECT count(*), datename(dw, reg_date) from #data
where datepart(week, reg_date) = 40
group by reg_date
drop table #data
assuming that you are using sql server greater or equal 2008!
I finally get the correct data for today and last 7 days. Please refer below query.
SELECT
a.JourneyName,
a.BonusName,
a.Status,
a."Timestamp",
a.MID,
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 0 THEN 1 ELSE NULL END) as "Day_1",
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 1 THEN 1 ELSE NULL END) as "Day_2",
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 2 THEN 1 ELSE NULL END) as "Day_3",
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 3 THEN 1 ELSE NULL END) as "Day_4",
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 4 THEN 1 ELSE NULL END) as "Day_5",
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 5 THEN 1 ELSE NULL END) as "Day_6",
COUNT(CASE WHEN DATEDIFF(DD, a."Timestamp", GETDATE()) = 6 THEN 1 ELSE NULL END) as "Day_7"
FROM
TableName a
WHERE
a."Timestamp" >= DATEADD(DD, -7, GETDATE())
AND a."Timestamp" <= GETDATE()
GROUP BY``
a.JourneyName, a.BonusName, a.Status, a."Timestamp", a.MID
Total Count per day where Day_1 is today, Day_2 is yesterday and so on.

How can I make this SQL query more elegant?

This is my MySQL query for getting count values...
SELECT 1 AS id,
'2016' AS Year,
MAX( IF( Month = '01', Count, 0 ) ) AS 'VAL01',
MAX( IF( Month = '02', Count, 0 ) ) AS 'VAL02',
MAX( IF( Month = '03', Count, 0 ) ) AS 'VAL03',
MAX( IF( Month = '04', Count, 0 ) ) AS 'VAL04',
MAX( IF( Month = '05', Count, 0 ) ) AS 'VAL05',
MAX( IF( Month = '06', Count, 0 ) ) AS 'VAL06',
MAX( IF( Month = '07', Count, 0 ) ) AS 'VAL07',
MAX( IF( Month = '08', Count, 0 ) ) AS 'VAL08',
MAX( IF( Month = '09', Count, 0 ) ) AS 'VAL09',
MAX( IF( Month = '10', Count, 0 ) ) AS 'VAL10',
MAX( IF( Month = '11', Count, 0 ) ) AS 'VAL11',
MAX( IF( Month = '12', Count, 0 ) ) AS 'VAL12',
SUM( Count ) AS Total
FROM ( SELECT DATE_FORMAT( created_at, '%m' ) AS Month,
COUNT( 1 ) AS Count
FROM reservations
WHERE DATE_FORMAT( created_at, '%Y' ) = '2016'
GROUP BY DATE_FORMAT( created_at, '%m' )
) AS T1
UNION
SELECT 2 AS id,
'2017' AS Year,
MAX( IF( Month = '01', Count, 0 ) ) AS 'VAL01',
MAX( IF( Month = '02', Count, 0 ) ) AS 'VAL02',
MAX( IF( Month = '03', Count, 0 ) ) AS 'VAL03',
MAX( IF( Month = '04', Count, 0 ) ) AS 'VAL04',
MAX( IF( Month = '05', Count, 0 ) ) AS 'VAL05',
MAX( IF( Month = '06', Count, 0 ) ) AS 'VAL06',
MAX( IF( Month = '07', Count, 0 ) ) AS 'VAL07',
MAX( IF( Month = '08', Count, 0 ) ) AS 'VAL08',
MAX( IF( Month = '09', Count, 0 ) ) AS 'VAL09',
MAX( IF( Month = '10', Count, 0 ) ) AS 'VAL10',
MAX( IF( Month = '11', Count, 0 ) ) AS 'VAL11',
MAX( IF( Month = '12', Count, 0 ) ) AS 'VAL12',
SUM( Count ) AS Total
FROM ( SELECT DATE_FORMAT( created_at, '%m' ) AS Month,
COUNT( 1 ) AS Count
FROM reservations
WHERE DATE_FORMAT( created_at, '%Y' ) = '2017'
GROUP BY DATE_FORMAT( created_at, '%m' )
) AS T2
It returns (for example)...
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| id | Year | VAL01 | VAL02 | VAL03 | VAL04 | VAL05 | VAL06 | ... | VAL12 | Total |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| 1 | 2016 | 0 | 0 | 150 | 190 | 200 | 220 | ... | 160 | 1242 |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| 2 | 2017 | 300 | 300 | 600 | 600 | 700 | 0 | ... | 0 | 2500 |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
My query has many problems. It can't use the year 2018 and it should use UNION again and again.
How can I make my SQL query more beautiful?
Try this
select
date_format(created_at,'%Y') as Year,
sum(case when date_format(created_at,'%m')='01' then 1 else 0 end) as val01,
sum(case when date_format(created_at,'%m')='02' then 1 else 0 end) as val02,
sum(case when date_format(created_at,'%m')='03' then 1 else 0 end) as val03,
sum(case when date_format(created_at,'%m')='04' then 1 else 0 end) as val04,
sum(case when date_format(created_at,'%m')='05' then 1 else 0 end) as val05,
sum(case when date_format(created_at,'%m')='06' then 1 else 0 end) as val06,
sum(case when date_format(created_at,'%m')='07' then 1 else 0 end) as val07,
sum(case when date_format(created_at,'%m')='08' then 1 else 0 end) as val08,
sum(case when date_format(created_at,'%m')='09' then 1 else 0 end) as val09,
sum(case when date_format(created_at,'%m')='10' then 1 else 0 end) as val10,
sum(case when date_format(created_at,'%m')='11' then 1 else 0 end) as val11,
sum(case when date_format(created_at,'%m')='12' then 1 else 0 end) as val12,
count(*) as total
from reservations
group by date_format(created_at,'%Y')
You can try with below query
SELECT YEAR,SUM(VAL01) VAL02,SUM(VAL02) VAL02,SUM(VAL03) VAL3
FROM
(
SELECT date_format(created_at,'%Y') YEAR,
CASE WHEN date_format(created_at,'%m')=1 THEN 1 ELSE 0 END AS VAL01,
CASE WHEN date_format(created_at,'%m')=2 THEN 1 ELSE 0 END AS VAL02,
CASE WHEN date_format(created_at,'%m')=3 THEN 1 ELSE 0 END AS VAL03
FROM reservations
)t
GROUP BY YEAR
Hope this will helps.
If this had been Oracle, you could have used Function based index on column Created_at and using the same function (EXTRACT in this case) in your query:
CREATE INDEX IDX1 ON RESERVATIONS (EXTRACT(YEAR FROM CREATED_AT))
Since, this is MySQL, try using this as alternative. Make sure after creating the index, it is getting used by verifying the Query plan.
You could try this query
SELECT id,
Year,
SUM(CASE WHEN Month='01' THEN MonthCount ELSE 0 END) AS 'VAL01',
SUM(CASE WHEN Month='02' THEN MonthCount ELSE 0 END) AS 'VAL02',
SUM(CASE WHEN Month='03' THEN MonthCount ELSE 0 END) AS 'VAL03',
SUM(CASE WHEN Month='04' THEN MonthCount ELSE 0 END) AS 'VAL04',
SUM(CASE WHEN Month='05' THEN MonthCount ELSE 0 END) AS 'VAL05',
SUM(CASE WHEN Month='06' THEN MonthCount ELSE 0 END) AS 'VAL06',
SUM(CASE WHEN Month='07' THEN MonthCount ELSE 0 END) AS 'VAL07',
SUM(CASE WHEN Month='08' THEN MonthCount ELSE 0 END) AS 'VAL08',
SUM(CASE WHEN Month='09' THEN MonthCount ELSE 0 END) AS 'VAL09',
SUM(CASE WHEN Month='10' THEN MonthCount ELSE 0 END) AS 'VAL10',
SUM(CASE WHEN Month='11' THEN MonthCount ELSE 0 END) AS 'VAL11',
SUM(CASE WHEN Month='12' THEN MonthCount ELSE 0 END) AS 'VAL12',
SUM(MonthCount) AS Total
FROM (
SELECT
CASE
WHEN Date_format(created_at, '%Y') = '2016' THEN 1
WHEN Date_format(created_at, '%Y') = '2017' THEN 2
WHEN Date_format(created_at, '%Y') = '2018' THEN 3
END AS id,
Date_format(created_at, '%Y') AS Year,
Date_format(created_at, '%m') AS Month,
COUNT(1) AS MonthCount
FROM reservations
WHERE Date_format(created_at, '%Y') IN ('2016', '2017', '2018')
GROUP BY Date_format(created_at, '%Y-%m')) AS ByMonth
GROUP BY id, Year

EMBEDDED DATEDIFF EXCLUD WEEKENDS + CASE STATEMENT

I have the below query that utilizes a case statement. I would like to datediff two dates but exclude weekend days.
I have the below that excutes but now I would like to exclude Sat and Sunday from this... AND DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) <= 2
CASE WHEN
S.Name IN ('Assessment','Survey')
AND A.ALERT_DESC = 'ER'
AND CAST(A.ALERTS_CREATE_DT AS DATE) <= CAST(S.CreatedDate AS DATE)
AND DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) <= 2 /*EXCLUDE Sat and Sunday from the calculation*/
Full Query
SELECT
CASE WHEN
S.Name IN ('Assessment','Survey')
AND A.ALERT_DESC = 'ER'
AND CAST(A.ALERTS_CREATE_DT AS DATE) <= CAST(S.CreatedDate AS DATE)
AND
( DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) <= 2 /*Business Days*/
--DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) + 1
---(DATEDIFF(WK,A.ALERTS_CREATE_DT,S.CreatedDate) * 2)
---(CASE WHEN DATENAME(DW,A.ALERTS_CREATE_DT) = 'SUNDAY' THEN 1 ELSE 0 END)
---(CASE WHEN DATENAME(DW,S.CreatedDate) = 'SATURADAY' THEN 1 ELSE 0 END)
)
THEN 'Y'
WHEN A.ALERT_DESC = 'model' OR S.CreatedDate IS NULL OR S.Name = 'ER'
THEN ''
ELSE 'N'
END 'Count towards Alerts'
FROM A
FULL S ON A.id= S.id
WHERE 1=1
This should give you the required result by excluding the Saturdays and Sundays.
SELECT A.ALERT_DESC,A.ALERTS_CREATE_DT,S.Name,S.CreatedDate,
CASE WHEN
S.Name IN ('Assessment','Survey') AND A.ALERT_DESC = 'ER'
AND CAST(A.ALERTS_CREATE_DT AS DATE) <= CAST(S.CreatedDate AS DATE)
AND
(( DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate)+1
- (datediff(wk,A.ALERTS_CREATE_DT,S.CreatedDate)*2)
- case when datepart(dw,A.ALERTS_CREATE_DT)=1 then 1 else 0 end
- case when datepart(dw,S.CreatedDate)=7 then 1 else 0 end
)) <=2 THEN 'Y'
WHEN A.ALERT_DESC = 'model' OR S.CreatedDate IS NULL OR S.Name = 'ER' THEN ''
ELSE 'N' END 'Count towards Alerts'
FROM A,S

Compare Months list with date field of table

I am using sql server 2008
I have table in my database is like this:
And I want output like this:
As it is shown in my table I have DateField which has smalldatetime datatype and along with fruits and vegi fields. I want output like which shows data month-wise.. month comparison should be performed based on DateField of my table.
You can use something like:
select [Month] = month(DateField)
, [MonthName] = left(datename(mm, DateField), 3)
, TotalAmountApple = sum(case when fruits = 'Apple' then 1 else 0 end)
, TotalAmountOnion = sum(case when vegi = 'Onion' then 1 else 0 end)
from produce
group by month(DateField)
, left(datename(mm, DateField), 3)
order by [Month]
Full test details (no SQL Fiddle as it's experiencing issues):
create table produce
(
id int
, fruits varchar(10)
, vegi varchar(10)
, DateField smalldatetime
)
insert into produce
select 1, 'Apple', 'Chilly', '01-jan-2013'
insert into produce
select 1, 'Mango', 'Onion', '15-jan-2013'
insert into produce
select 1, 'Mango', 'Chilly', '20-jan-2013'
insert into produce
select 1, 'Apple', 'Chilly', '01-Feb-2013'
insert into produce
select 1, 'Mango', 'Onion', '15-Feb-2013'
insert into produce
select 1, 'Apple', 'Onion', '20-Feb-2013'
select [Month] = month(DateField)
, [MonthName] = left(datename(mm, DateField), 3)
, TotalAmountApple = sum(case when fruits = 'Apple' then 1 else 0 end)
, TotalAmountOnion = sum(case when vegi = 'Onion' then 1 else 0 end)
from produce
group by month(DateField)
, left(datename(mm, DateField), 3)
order by [Month]