SQL GROUP BY AND VALUE AND NON UNIQUE VALUES - sql

This is my SQL:
SELECT *
FROM (
SELECT DISTINCT real_dep_date,
real_price,
resort_name,
season_id,
min_occ,
free_sell,
MIN(real_price) OVER (PARTITION BY resort_name,real_dep_date) AS min_price
FROM deals_panel_view
WHERE ([1pax_disc] = [1pax_disc])
AND (real_dep_date >= season_start)
AND (season_name = 'winter 2012')
AND (chalet_url <> '')
AND (real_price <> 0)
AND (real_dep_date <= season_end)
AND (combined_chalet = 0)
AND (availability_spaces <> 0)
) deals_panel_view
WHERE min_price = real_price
This works but what happens is I get 3 results for a certain resort. This is because there are 3 chalets that are exactly the same.
I want to only show one, so I guess I would use a limit, but I don't know where.
I am using SQL Server 2005.
Any help would be great.

Try with this...
Select real_dep_date,
real_price,
resort_name,
season_id,
min_occ,
free_sell,
min_price FROM (SELECT ROW_NUMBER() over (PARTITION BY resort_name,real_dep_date ORDER BY resort_name) as ROW,*
FROM (
SELECT DISTINCT real_dep_date,
real_price,
resort_name,
season_id,
min_occ,
free_sell,
MIN(real_price) OVER (PARTITION BY resort_name,real_dep_date) AS min_price
FROM deals_panel_view
WHERE ([1pax_disc] = [1pax_disc])
AND (real_dep_date >= season_start)
AND (season_name = 'winter 2012')
AND (chalet_url <> '')
AND (real_price <> 0)
AND (real_dep_date <= season_end)
AND (combined_chalet = 0)
AND (availability_spaces <> 0)
) deals_panel_view
WHERE min_price = real_price
) Temp
where Row = 1

Related

Converting Subquery into Single Query

I've a query that has multiple subqueries with parameters as follows:
SELECT
V.EMPNO,
V.FIRST_NAME || ' ' || V.MIDDLE_NAME
|| ' '
|| V.LAST_NAME FULLNAME,
M.APP_NO,
K.TOTAL_AMT,
K.TOTAL_AMT - (SELECT
SUM(Q.RECAMOUNT)
FROM
LOAN_ADJ_DETAILS_NEW q
WHERE
Q.APP_NO = M.APP_NO
AND Q.RECDATE <= '01-AUG-2022') REMAINING,
(SELECT
SUM(P.RECAMOUNT)
FROM
LOAN_ADJ_DETAILS_NEW p
WHERE
P.APP_NO = M.APP_NO
AND P.RECDATE <= '01-AUG-2022') TOTALADJ,
(SELECT
COUNT(*)
FROM
LOAN_ADJ_DETAILS_NEW p
WHERE
P.APP_NO = M.APP_NO
AND P.RECDATE IS NOT NULL
AND P.RECDATE <= '01-AUG-2022') INSTALLMENT,
(SELECT
MAX(Q.RECAMOUNT)
FROM
LOAN_ADJ_DETAILS_NEW q
WHERE
Q.APP_NO = M.APP_NO
AND Q.RECDATE = '01-AUG-2022') LASTINSTALL,
(SELECT
MAX(S.RECDATE)
FROM
LOAN_ADJ_DETAILS_NEW s
WHERE
S.APP_NO = M.APP_NO
AND S.RECDATE <= '01-AUG-2022') LASTDATE,
(SELECT
SUM(P.RECAMOUNT)
FROM
LOAN_ADJ_DETAILS_NEW p
WHERE
P.APP_NO = M.APP_NO
AND P.RECDATE <= '01-AUG-2022') PAID
FROM
LOAN_ADJ_DETAILS_NEW m,
TBL_LOAN_MASTER k,
EMP_PERSONAL v
WHERE
V.EMPNO = M.EMPNO
AND K.LOAN_ID = M.APP_NO
AND M.RECAMOUNT > 0
AND M.RECDATE IS NOT NULL
AND M.RECDATE = '01-AUG-2022'
AND M.RECDATE >= '01-AUG-2022';
The query is simple, just to get user wise loan information. Now the thing is, I require to make it into one query something as follows:
SELECT * FROM TABLE WHERE COLUMN <= PARAMTER;
The above query will be used as a dynamic query from database to front-end. I was hoping if this could be converted to a single query or view anyway.
You can use analytic functions and combine the sub-queries into a single one in the FROM clause:
SELECT V.EMPNO,
V.FIRST_NAME || ' ' || V.MIDDLE_NAME || ' ' || V.LAST_NAME
AS FULLNAME,
M.APP_NO,
K.TOTAL_AMT,
K.TOTAL_AMT - m.paid AS REMAINING,
m.totaladj,
m.paid,
m.installment,
m.lastinstall,
m.lastdate
FROM ( SELECT app_no,
empno,
recamount,
recdate,
SUM(RECAMOUNT) OVER (PARTITION BY app_no) AS totaladj,
SUM(RECAMOUNT) OVER (PARTITION BY app_no) AS paid,
COUNT(*) OVER (PARTITION BY app_no) AS installment,
MAX(RECAMOUNT) OVER (PARTITION BY app_no) AS lastinstall,
MAX(RECDATE) OVER (PARTITION BY app_no) AS lastdate
FROM LOAN_ADJ_DETAILS_NEW
WHERE RECDATE <= DATE '2022-08-01'
) m
INNER JOIN TBL_LOAN_MASTER k
ON (K.LOAN_ID = M.APP_NO)
INNER JOIN EMP_PERSONAL v
ON (V.EMPNO = M.EMPNO)
WHERE M.RECAMOUNT > 0
AND M.RECDATE = DATE '2022-08-01';

how to delete from table based on query results

I have the following query which spits out some values and I need to basically modify it so that I can delete some rows from the source table based on whether the Ticker symbol and date are represented in the output of the select query.
Here is the query.
;with cte_tenPct as (
select exchange, ticker
, CurrentDate = date, Prior_Date = (lag(date) over(partition by ticker order by date))
, Current_open = [open] , Prior_open = (lag([open]) over(partition by ticker order by date))
, Current_high = [high] , Prior_high = (lag([high]) over(partition by ticker order by date))
, Current_low = [low] , Prior_low = (lag([low]) over(partition by ticker order by date))
, Current_close = [close] , Prior_close = (lag([close]) over(partition by ticker order by date))
from dbo.V with (nolock)
)
select * from cte_tenPct
where (Current_open <> 0 and Current_open = Prior_open / 10)
and (Current_high <> 0 and Current_high = Prior_high / 10)
and (Current_low <> 0 and Current_low = Prior_low / 10)
and (Current_close <> 0 and Current_close = Prior_close / 10)
Here are the results (just the relevant parts)
So, I want to basically start the query with: DELETE FROM V where V.Ticker = cte_tenPct.Ticker and V.Date = cte_tenPct.CurrentDate IN --then I would have the select query below. Can someone help me out with the syntax. Thanks
;with cte_tenPct as (
select exchange, ticker
, CurrentDate = date, Prior_Date = (lag(date) over(partition by ticker order by date))
, Current_open = [open] , Prior_open = (lag([open]) over(partition by ticker order by date))
, Current_high = [high] , Prior_high = (lag([high]) over(partition by ticker order by date))
, Current_low = [low] , Prior_low = (lag([low]) over(partition by ticker order by date))
, Current_close = [close] , Prior_close = (lag([close]) over(partition by ticker order by date))
from dbo.V with (nolock)
)
delete from cte_tenPct
where (Current_open <> 0 and Current_open = Prior_open / 10)
and (Current_high <> 0 and Current_high = Prior_high / 10)
and (Current_low <> 0 and Current_low = Prior_low / 10)
and (Current_close <> 0 and Current_close = Prior_close / 10)
Basically you just need to delete instead of selecting the cte resutls.
And of cource you can either delete all entries that exist in the cte results or use a where clause to filter which entries will be deleted.

The query I ran returns 2 of the same column which isn't allowed in tableau and I can't fix the query

I need to be able to get rid of one of the workdate and one of the sr_name columns but I can't figure out how to.
I'm getting the query returned like this:
Query
I'm also getting this error message when entered into tableau:
The column 'sr_name' was specified multiple times for 'Custom SQL Query'.
Below is the code I have. If I remove a sr_name from either subquery there will be an error in the join clause.
select *
from
(
select s.sr_name, cast(punchdatetime as date) as workdate,
((datediff(second, min(case when p.InOut = 1 then punchdatetime end),
max(case when p.InOut = 0 then punchdatetime end))/3600) - .5) as
hoursworked
from PunchClock p join ServiceReps s on p.ServRepID = s.ServRepID
where punchyear >= 2019
group by s.sr_name, cast(punchdatetime as date)
) v
join
(
select sr_name, t.*,
calls = (select count(*) from CRM_Correspondence cr where
cast(cr.DateCreated as date) = workdate and StatusType like '%call%' and
cr.ServRepID = t.servrepid),
reaches = (select count(*) from CRM_Correspondence cr where
cast(cr.DateCreated as date) = workdate and (StatusType = 'call reached'
or StatusType like '%SCHEDULE%') and cr.ServRepID = t.servrepid),
books = (select count(*) from os_appointments o where cast(o.DateCreated
as date) = workdate and isnull(o.confirmedby, o.booked_by) =
t.servrepid),
attends = (select count(*) from os_appointments o where
cast(o.DateCreated as date) = workdate and isnull(o.confirmedby,
o.booked_by) = t.servrepid and o.appointmentStatus = 'attended')
from
(
select cast(cor.datecreated as date) workdate, cor.ServRepID
from CRM_Correspondence cor
where cor.datecreated > '2019-01-01'
group by cast(cor.datecreated as date), cor.servrepid
) t
join ServiceReps sr on t.ServRepID = sr.ServRepID
) u on v.sr_name = u.sr_name and v.workdate = u.workdate
I need the same results just without the duplicate column so I can enter the query into tableau.
This is challenging because you have so many subqueries here. This could be refactored to use a single query which is what I would do. But using the existing query you could do something along these lines.
I had to format this very differently so I could isolate each piece.
select v.sr_name
, v.workdate
, v.hoursworked
, u.ServRepID
, u.calls
, u.reaches
, u.books
, u.attends
from
(
select s.sr_name
, cast(punchdatetime as date) as workdate
, ((datediff(second, min(case when p.InOut = 1 then punchdatetime end), max(case when p.InOut = 0 then punchdatetime end))/3600) - .5) as hoursworked
from PunchClock p
join ServiceReps s on p.ServRepID = s.ServRepID
where punchyear >= 2019
group by s.sr_name
, cast(punchdatetime as date)
) v
join
(
select sr_name
, t.*
, calls =
(
select count(*)
from CRM_Correspondence cr
where cast(cr.DateCreated as date) = workdate
and StatusType like '%call%'
and cr.ServRepID = t.servrepid
)
, reaches =
(
select count(*)
from CRM_Correspondence cr
where cast(cr.DateCreated as date) = workdate
and (StatusType = 'call reached' or StatusType like '%SCHEDULE%')
and cr.ServRepID = t.servrepid
)
, books =
(
select count(*)
from os_appointments o
where cast(o.DateCreated as date) = workdate and isnull(o.confirmedby, o.booked_by) = t.servrepid
)
, attends =
(
select count(*)
from os_appointments o
where cast(o.DateCreated as date) = workdate
and isnull(o.confirmedby, o.booked_by) = t.servrepid
and o.appointmentStatus = 'attended'
)
from
(
select cast(cor.datecreated as date) workdate
, cor.ServRepID
from CRM_Correspondence cor
where cor.datecreated > '2019-01-01'
group by cast(cor.datecreated as date)
, cor.servrepid
) t
join ServiceReps sr on t.ServRepID = sr.ServRepID
) u on v.sr_name = u.sr_name
and v.workdate = u.workdate

Find median between 2 dates

Anyone know how I can change the Total Median near bottom to show an average of the median instead? For some reason, the Total Median is always 100. Not sure what I should do.
Thanks in advance for any ideas! Current results also below.
WITH CTE AS (
SELECT DISTINCT c.CaseID AS CaseID,
DATEDIFF(d, c.CaseAddDt, coip.DispoDt) AS DaysApart
, DATEPART(month,c.CaseAddDt) AS [Month]
, DATEPART(year,c.CaseAddDt) AS [Year]
, CAST(DATEPART(year,c.CaseAddDt) AS varchar) + '|' + CASE WHEN DATEPART(month,c.CaseAddDt) IN (10,11,12) THEN CAST(DATEPART(month,c.CaseAddDt) AS varchar) ELSE '0' + CAST(DATEPART(month,c.CaseAddDt) AS varchar) END AS Srt
FROM jw50_Case c
JOIN jw50_CaseInvPers def ON def.CaseID = c.CaseID
AND def.InvolveTypeMasterCode = 1
JOIN
jw50_CountInvPers coip ON coip.CaseID = c.CaseID
AND coip.CaseInvPersID = def.CaseInvPersID
AND coip.DispoCode IN ('CODE','CODE')
AND coip.CountNum > 0
OUTER APPLY (
SELECT TOP 1 caz.CaseAgencyID
FROM jw50_CaseAgency caz
WHERE caz.CaseID = c.CaseID
AND caz.AgencyCode = 'ABC'
AND caz.NumberTypeCode IN ('i#','in#')) caz
WHERE
EXISTS (SELECT 1 FROM jw50_CaseAttributes ca WHERE ca.CaseID = c.CaseID AND ca.CaseAttributeCode = 'oa7')
AND caz.CaseAgencyID IS NOT NULL
AND c.CaseStatusCode <> 'AAA'
AND c.CaseAddDt BETWEEN '01/01/2017' AND '08/01/2017'
AND c.CaseAddDt <= coip.DispoDt)
SELECT a.CaseID,
a.Month
, a.Year
, a.DaysApart
, a.Srt
, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY a.DaysApart) OVER (PARTITION BY a.Month, a.Year) AS MonMedian
, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY a.DaysApart) OVER (PARTITION BY 1) AS TotalMedian
FROM CTE a
Results:

CASE Statement inside a subquery

I was able to create the following query after help from the post below
select * from duppri t
where exists (
select 1
from duppri
where symbolUP = t.symbolUP
AND date = t.date
and price <> t.price)
ORDER BY date
SQL to check when pairs don't match
I have now realized that I need to add a case statement to indicate when all the above criteria fits, but the type value is equal between duppri and t.duppri. This occurs because of case sensitivity. This query is an attempt to clean up a portfolio accounting system that unfortunately allowed numerous duplicates because it didn't have strong referential integrity or constraints.
I would like the case statement to produce the column 'isMatch'
Date |Type|Symbol |SymbolUP |Concatt |Price |IsMatch
6/30/1995 |gaus|313586U72|313586U72|gaus313586U72|109.25|Different
6/30/1995 |gbus|313586U72|313586U72|gbus313586U72|108.94|Different
6/30/1995 |agus|SRR |SRR |agusSRR |10.25 |Different
6/30/1995 |lcus|SRR |SRR |lcusSRR |0.45 |Different
11/27/1996|lcus|LLY |LLY |lcusLLY |76.37 |Matched
11/27/1996|lcus|lly |LLY |lcusLLY |76 |Matched
11/28/1996|lcus|LLY |LLY |lcusLLY |76.37 |Matched
11/28/1996|lcus|lly |LLY |lcusLLY |76 |Matched
I tried the following CASE statement but it is creating errors
SELECT * from duppri t
where exists (
select 1,
CASE IsMatch WHEN [type] = [t.TYPE] THEN 'Matched' ELSE 'Different' END
from duppri
where symbolUP = t.symbolUP
AND date = t.date
and price <> t.price)
ORDER BY date
You could just use window functions, if I understand correctly:
select d.*,
(case when mint = maxt
then 'Matched' else 'Different'
end)
from (select d.*,
min(type) over (partition by symbolup, date) as mint,
max(type) over (partition by symbolup, date) as maxt,
min(price) over (partition by symbolup, date) as minp,
max(price) over (partition by symbolup, date) as maxp
from duppri d
) d
where minp <> maxp
order by date;
The subquery used with the exists predicate can't and won't return anything other than true/false but you can accomplish what you want using a subquery like this, which should work:
select
*,
(select
CASE when count(distinct type) = 1 THEN 'Matched' ELSE 'Different' END
from duppri
where symbol = t.symbol and date = t.date
) IsMatch
from duppri t
where exists (
select 1
from duppri
where symbol = t.symbol
and price <> t.price);