INCORRECT SUM() OUTPUT on LEFT JOIN CASE QUERY - sql

when i select the specific table and use the case method to get only the max value of 8 there is no problem with it.
but when i use the 1st query and join it to get the SUM value of totalhrs it gave me different value
REFERENCE TABLE WORKING
SELECT l1.userid,(l2.fname+' '+l2.lname) as empname,l2.department,l1.date,MIN(l1.time_in) as timein,MAX(l1.time_in) as timeout,CASE WHEN DATEDIFF(MINUTE,CONVERT(datetime,MIN(l1.time_in)) ,CONVERT(datetime,MAX(l1.time_in)))/60.0 > 8 THEN 8 ELSE DATEDIFF(MINUTE,CONVERT(datetime,MIN(l1.time_in)) ,CONVERT(datetime,MAX(l1.time_in)))/60.0 END as totalhrs
,CASE WHEN DATEDIFF(minute,'08:00',MIN(l1.time_in)) > 0 THEN DATEDIFF(minute,'08:00',MIN(l1.time_in)) ELSE 0 END as late,
CASE WHEN DATEDIFF(minute,MAX(l1.time_in),'17:00') > 0 THEN DATEDIFF(minute,MAX(l1.time_in),'17:00') ELSE 0 END as undertime,MAX(image_in) as imgo,MIN(image_in) as imgi
from hgs_hr_attendancelogs l1
LEFT JOIN (SELECT userid,lname,fname,department from user_acc)l2
ON l1.userid = l2.userid
WHERE l1.userid = '442' and l1.date between '2021-03-16' and '2021-03-31'
group by l1.userid,l1.date,l2.fname,l2.lname,l2.department
ORDER BY l1.userid
OUTPUT IN SUM INSTEAD ADD THE 4th column(THE SUM IS 78) it gives 2668.17
SELECT l1.userid,SUM(l2.totalhrs),COUNT(l2.late)
FROM hgs_hr_attendancelogs l1
LEFT JOIN(SELECT l1.userid,(l2.fname+' '+l2.lname) as empname,l2.department,l1.date,MIN(l1.time_in) as timein,MAX(l1.time_in) as timeout,
CAST(CASE WHEN DATEDIFF(MINUTE,CONVERT(datetime,MIN(l1.time_in)) ,CONVERT(datetime,MAX(l1.time_in)))/60.0 > 8 THEN 8 ELSE DATEDIFF(MINUTE,CONVERT(datetime,MIN(l1.time_in)) ,CONVERT(datetime,MAX(l1.time_in)))/60.0 END as DECIMAL(18,2)) totalhrs
,CASE WHEN DATEDIFF(minute,'08:00',MIN(l1.time_in)) > 0 THEN DATEDIFF(minute,'08:00',MIN(l1.time_in)) ELSE 0 END as late,
CASE WHEN DATEDIFF(minute,MAX(l1.time_in),'17:00') > 0 THEN DATEDIFF(minute,MAX(l1.time_in),'17:00') ELSE 0 END as undertime,MAX(image_in) as imgo,MIN(image_in) as imgi
from hgs_hr_attendancelogs l1
LEFT JOIN (SELECT userid,lname,fname,department from user_acc)l2
ON l1.userid = l2.userid
group by l1.userid,l1.date,l2.fname,l2.lname,l2.department ) l2
ON l1.userid = l2.userid
WHERE l2.date between '2021-03-16' and '2021-03-31'
GROUP BY l1.userid

Think you dont need the second join hgs_hr_attendancelogs (in not working query). A query like below should work. please check.
select
t1.userid, SUM(t1.totalhrs),COUNT(t1.late)
from
(
--working
SELECT
l1.userid,(l2.fname+' '+l2.lname) as empname,l2.department,l1.date,MIN(l1.time_in) as timein,MAX(l1.time_in) as timeout,
CASE
WHEN DATEDIFF(MINUTE,CONVERT(datetime,MIN(l1.time_in)) ,CONVERT(datetime,MAX(l1.time_in)))/60.0 > 8
THEN 8
ELSE
DATEDIFF(MINUTE,CONVERT(datetime,MIN(l1.time_in)) ,CONVERT(datetime,MAX(l1.time_in)))/60.0
END as totalhrs,
CASE
WHEN DATEDIFF(minute,'08:00',MIN(l1.time_in)) > 0
THEN DATEDIFF(minute,'08:00',MIN(l1.time_in))
ELSE
0
END as late,
CASE
WHEN DATEDIFF(minute,MAX(l1.time_in),'17:00') > 0
THEN DATEDIFF(minute,MAX(l1.time_in),'17:00')
ELSE
0
END as undertime,
MAX(image_in) as imgo,
MIN(image_in) as imgi
from
hgs_hr_attendancelogs l1
LEFT JOIN (SELECT userid,lname,fname,department from user_acc)l2 ON l1.userid = l2.userid
WHERE
l1.userid = '442'
and l1.date between '2021-03-16' and '2021-03-31'
group by
l1.userid,l1.date,l2.fname,l2.lname,l2.department
) t1
group by
l1.userid
ORDER BY
l1.userid
And reg the 'query not working', did you try moving the l2.date between '2021-03-16' and '2021-03-31' inside the left join?
Thanks

Related

SQL code to set a specific date as compared to "today's" date

In the first column (Report_Date) of this query the date is being constructed and is today's day, and is used in the following lines to select is the following columns. I'd like to use a specific day in the query.
I'd like help to write the format to replace column 1 (Report_Date) with a different date to create aging, like June 1st - 2021-06-01.
SELECT
convert(datetime,convert(char,datepart(mm,getdate()))+'/'+convert(char,datepart(dd,getdate()))+'/'+convert(char,datepart(yyyy,getdate())))Report_Date,
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 0 and 30 then B.CurrentBalance else 0
end) '0-30',
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 31 and 60 then B.CurrentBalance else 0
end) '31-60',
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 61 and 90 then B.CurrentBalance else 0
end) '61-90',
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 91 and 120 then B.CurrentBalance else 0
end) '91-120',
B.Primary_Payer_Code,
B.Secondary_Payer_Code,
B.CurrentResponsibility_desc,
Case When G.PAYER_GROUP IS NOT NULL Then G.PAYER_GROUP
Else Case When B.Primary_Payer_Code = 'PP' Then 'SELF PAY' Else
F.Description End End
FROM
Date D with (nolock)
JOIN TEL_BILLED_LINE_ITEM_ODS B with (nolock) ON ( convert(datetime,convert(char,B.Original_Bill_Date,101)) = D.DATE)
LEFT OUTER JOIN TBLPAYER_ODS P with (nolock) ON B.Primary_Payer_Code=P.Code
LEFT OUTER JOIN TBLFINANCIALCLASS_ODS F with (nolock) ON F.tblfinancialclassid = P.FinancialClassID
LEFT OUTER JOIN PAYER_GROUP G ON G.PAYER_CODE = P.CODE
WHERE
( B.CurrentBalance != 0)
AND B.BadDebtFlagYN=0
AND B.Primary_Payer_Code !='CL' -- exclude CLIENT 07/01/2010 jdw
GROUP BY
B.Primary_Payer_Code,
B.Secondary_Payer_Code,
B.CurrentResponsibility_desc,
Case When G.PAYER_GROUP IS NOT NULL Then G.PAYER_GROUP
Else Case When B.Primary_Payer_Code = 'PP' Then 'SELF PAY' Else
F.Description End End

How to get Sql Temp Table Join with column values that are not in table, replaced by 0

I have 5 temp tables that I want to combine into a new temp table via the month_year column and the prod_id. Where the columns are not prod_id or month_year and values are not available, I want that column's value(e.g. job_amt or received_qty) to be 0.
#tmp_spoilt_good_job_amt
month_year job_amt spoil good prod_id
07-2017 40 10 20 2
08-2017 827 0 210 3
09-2017 27 1 27 2
09-2017 732 22 345 3
10-2017 50 0 6 2
10-2017 1130 55 50 3
11-2017 300 0 0 4
#tmp_received_qty
month_year received_qty prod_id
08-2017 32 2
08-2017 2500 3
09-2017 2200 2
11-2017 2500 4
#tmp_purchase_qty
month_year purchase_qty prod_id
09-2017 11 2
#tmp_opening_balance
month_year opening_balance prod_id
08-2017 32 2
08-2017 2500 3
09-2017 22 2
09-2017 2300 3
10-2017 2163 2
10-2017 2023 3
11-2017 2500 4
#tmp_closing_balance
month_year closing_balance prod_id
08-2017 2300 3
08-2017 32 2
09-2017 2213 2
09-2017 1998 3
10-2017 1687 3
10-2017 2163 2
11-2017 2400 4
I tried some inner joins but the values were repeating or some were not reflecting. what query could I use to get these combined?
I am looking for the following output:
CREATE TABLE #table_with_all_months_prod_ids_using_cross_join (month_year, prod_id)
GO
INSERT #table_with_all_months_prod_ids_using_cross_join
SELECT t1.month_year, t2.prod_id
FROM monthyeartable t1
CROSS JOIN prodidtable t2
SELECT DISTINCT t0.month_year, t0.prod_id, ISNULL(t1.job_amt,0), ISNULL(t1.spoil,0), ISNULL(t1.good,0), ISNULL(t2.received_qty,0), ISNULL(t3.purchase_qty,0), ISNULL(t4.opening_balance,0), ISNULL(t5.closing_balance,0)
FROM #table_with_all_months_prod_ids_using_cross_join t0
LEFT JOIN #tmp_spoilt_good_job_amt t1 ON t0.month_year = t1.month_year AND t0.prod_id = t1.prod_id
LEFT JOIN #tmp_received_qty t2 ON t0.month_year = t2.month_year AND t0.prod_id = t2.prod_id
LEFT JOIN #tmp_purchase_qty t3 ON t0.month_year = t3.month_year AND t0.prod_id = t3.prod_id
LEFT JOIN #tmp_opening_balance t4 ON t0.month_year = t4.month_year AND t0.prod_id = t4.prod_id
LEFT JOIN #tmp_closing_balance t5 ON t0.month_year = t5.month_year AND t0.prod_id = t5.prod_id
WHERE NOT (t1.job_amt IS NULL AND t1.spoil IS NULL AND t1.good IS NULL AND t2.received_qty IS NULL AND t3.purchase_qty IS NULL AND t4.opening_balance IS NULL AND t5.closing_balance IS NULL)
So, this kind of relation ships have very week performance, first of all it is better to change the tables structure and all other thing that related to fill data in you database.
Any way, this query created for your current needs with current data structure, also if you work on this query or divided it in to some views maybe you can improve performance:
SELECT CASE WHEN ISNULL(srpo.month_year , '-1') <> '-1' THEN srpo.month_year
WHEN ISNULL(c.month_year , '-1') <> '-1' THEN c.month_year
END AS month_year,
CASE WHEN ISNULL(srpo.prod_id, -1) <> -1 THEN srpo.prod_id
WHEN ISNULL (c.prod_id, -1) <> -1 THEN c.prod_id
END AS prod_id,
CASE WHEN ISNULL(c.closing_balance, -1) = -1 THEN 0 else c.closing_balance END AS closing_balance,
srpo.job_amt,srpo.spoil,srpo.good ,srpo.received_qty,srpo.purchase_qty, srpo.opening_balance
FROM #tmp_closing_balance AS c FULL OUTER JOIN
(SELECT CASE WHEN ISNULL(srp.month_year , '-1') <> '-1' THEN srp.month_year
WHEN ISNULL(o.month_year , '-1') <> '-1' THEN o.month_year
END AS month_year,
CASE WHEN ISNULL(srp.prod_id, -1) <> -1 THEN srp.prod_id
WHEN ISNULL (o.prod_id, -1) <> -1 THEN o.prod_id
END AS prod_id,
CASE WHEN ISNULL(o.opening_balance, -1) = -1 THEN 0 else o.opening_balance END AS opening_balance,
srp.job_amt,srp.spoil,srp.good ,srp.received_qty,srp.purchase_qty
FROM #tmp_opening_balance AS o FULL OUTER JOIN
(SELECT CASE WHEN ISNULL(sr.month_year , '-1') <> '-1' THEN sr.month_year
WHEN ISNULL(p.month_year , '-1') <> '-1' THEN p.month_year
END AS month_year,
CASE WHEN ISNULL(sr.prod_id, -1) <> -1 THEN sr.prod_id
WHEN ISNULL (p.prod_id, -1) <> -1 THEN p.prod_id
END AS prod_id,
CASE WHEN ISNULL(p.purchase_qty, -1) = -1 THEN 0 else p.purchase_qty END AS purchase_qty,
sr.job_amt,sr.spoil,sr.good ,sr.received_qty
FROM #tmp_purchase_qty AS p FULL OUTER JOIN
(SELECT CASE WHEN ISNULL(s.month_year , '-1') <> '-1' THEN s.month_year
WHEN ISNULL(r.month_year , '-1') <> '-1' THEN r.month_year
END AS month_year,
CASE WHEN ISNULL(s.prod_id, -1) <> -1 THEN s.prod_id
WHEN ISNULL (r.prod_id, -1) <> -1 THEN r.prod_id
END AS prod_id,
CASE WHEN ISNULL(s.job_amt, -1) = -1 THEN 0 else s.job_amt END AS job_amt,
CASE WHEN ISNULL(s.spoil, -1) = -1 THEN 0 else s.spoil END AS spoil,
CASE WHEN ISNULL(s.good, -1) = -1 THEN 0 else s.good END AS good,
CASE WHEN ISNULL(r.received_qty, -1) = -1 THEN 0 else r.received_qty END AS received_qty
FROM #tmp_spoilt_good_job_amt AS s FULL OUTER JOIN
#tmp_received_qty AS r ON s.prod_id = r.prod_id AND
LTRIM(rtrim(s.month_year)) = LTRIM(rtrim(r.month_year))) AS sr ON
sr.prod_id = p.prod_id AND LTRIM(rtrim(sr.month_year)) = LTRIM(rtrim(p.month_year)) ) AS srp ON
srp.prod_id = o.prod_id AND LTRIM(rtrim(srp.month_year)) = LTRIM(rtrim(o.month_year))) AS srpo ON
srpo.prod_id = c.prod_id AND LTRIM(rtrim(srpo.month_year)) = LTRIM(rtrim(c.month_year))
I use FULL OUTER JOIN for all part of query because you mentioned that, may be all tables have possible values for keys columns(month_year and prod_id).
First if you have these 5 temp tables that probably means there is a much much much better way of doing this at the source table level! But because you asked you most significant problem with combining them is that not 1 of the tables hold a combination of every month_year and prod_id. So you have to create it. The way I choose to do this for completeness sake is to:
Create a Tally table (as a common table expression [CTE]) for use in
generating a month_year table
Create a Products CTE by unioning all distinct prod_ids from your temp tables
Create a MonthYearInputs CTE to be able to determine the Max and Min month_years represented
Generate a MonthYear CTE to house every possible month_year combination between the MIN & MAX years represented in your data
Then a cartisean (CROSS) join between the MonthYear & Product ctes give you all of the combinations to LEFT JOIN the other tables to.
Simply put a where statement in to remove the rows that have no values in ALL of the tables and use ISNULL() or COALESCE() to make the null values 0.
Here is a working example: http://rextester.com/MCEO96178
;WITH cteTen AS (
SELECT n FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n)
)
, cteTally AS (
SELECT
n = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
cteTen t1
CROSS JOIN cteTen t2 --hundreds
CROSS JOIN cteTen t3 --thousands
--keep cross joining if need more than 1000 month
)
, cteProducts AS (
SELECT DISTINCT prod_id FROM #tmp_spoilt_good_job_amt
UNION
SELECT DISTINCT prod_id FROM #tmp_received_qty
UNION
SELECT DISTINCT prod_id FROM #tmp_purchase_qty
UNION
SELECT DISTINCT prod_id FROM #tmp_opening_balance
UNION
SELECT DISTINCT prod_id FROM #tmp_closing_balance
)
, cteInputMonthYears AS (
SELECT DISTINCT month_year FROM #tmp_spoilt_good_job_amt
UNION
SELECT DISTINCT month_year FROM #tmp_received_qty
UNION
SELECT DISTINCT month_year FROM #tmp_purchase_qty
UNION
SELECT DISTINCT month_year FROM #tmp_opening_balance
UNION
SELECT DISTINCT month_year FROM #tmp_closing_balance
)
, cteMaxMinMonthYears AS (
SELECT
MinMonthYear = CAST(STUFF(MIN(month_year),3,0,'-01') AS DATETIME)
,MonthsDiff = DATEDIFF(MONTH,CAST(STUFF(MIN(month_year),3,0,'-01') AS DATETIME),CAST(STUFF(MAX(month_year),3,0,'-01') AS DATETIME)) + 1
FROM
cteInputMonthYears
)
, cteMonthYears AS (
SELECT
month_year = FORMAT(DATEADD(MONTH, t.n - 1, m.MinMonthYear),'MM-yyyy')
FROM
cteMaxMinMonthYears m
INNER JOIN cteTally t
ON m.MonthsDiff >= t.n
)
SELECT
my.month_year
,job_amt = ISNULL(ja.job_amt,0)
,spoil = ISNULL(ja.spoil,0)
,good = ISNULL(ja.good,0)
,p.prod_id
,received_qty = ISNULL(r.received_qty,0)
,purchase_qty = ISNULL(pur.purchase_qty,0)
,opening_balance = ISNULL(o.opening_balance,0)
,closing_balance = ISNULL(c.closing_balance,0)
FROM
cteMonthYears my
CROSS JOIN cteProducts p
LEFT JOIN #tmp_spoilt_good_job_amt ja
ON my.month_year = ja.month_year
AND p.prod_id = ja.prod_id
LEFT JOIN #tmp_received_qty r
ON my.month_year = r.month_year
AND p.prod_id = r.prod_id
LEFT JOIN #tmp_purchase_qty pur
ON my.month_year = pur.month_year
AND p.prod_id = pur.prod_id
LEFT JOIN #tmp_opening_balance o
ON my.month_year = o.month_year
AND p.prod_id = o.prod_id
LEFT JOIN #tmp_closing_balance c
ON my.month_year = c.month_year
AND p.prod_id = c.prod_id
WHERE
NOT(ja.month_year IS NULL
AND r.month_year IS NULL
AND pur.month_year IS NULL
AND o.month_year IS NULL
AND o.month_year IS NULL
AND c.month_year IS NULL)
ORDER BY
my.month_year
,p.prod_id
Personally, I think you should go with #influent's suggest: derive a template table on to which you can left the values you're looking for.
In the eventuality that you don't have the required logic or data to accurately derive such a template table, there is another option.
1. Pad out each table with dummy 0 values, so that they all have the same fields
2. UNION all the tables together
3. GROUP all the results back down to one row per month per product
WITH
padded_combined
AS
(
SELECT month_year, prod_id, job_amt, spoil, good, 0 AS received_qty, 0 AS purchase_qty, 0 AS opening_balance, 0 AS closing_balance FROM #tmp_spoilt_good_job_amt
UNION ALL
SELECT month_year, prod_id, 0, 0, 0, received_qty, 0, 0, 0 FROM #tmp_received_qty
UNION ALL
SELECT month_year, prod_id, 0, 0, 0, 0, purchase_qty, 0, 0 FROM #tmp_purchase_qty
UNION ALL
SELECT month_year, prod_id, 0, 0, 0, 0, 0, opening_balance, 0 FROM #tmp_opening_balance
UNION ALL
SELECT month_year, prod_id, 0, 0, 0, 0, 0, 0, closing_balance FROM #tmp_closing_balance
)
SELECT
month_year,
prod_id,
SUM(job_amt) AS job_amt,
SUM(spoil) AS spoil,
SUM(good) AS good,
SUM(received_qty) AS received_qty,
SUM(purchase_qty) AS purchase_qty,
SUM(opening_balance) AS opening_balance,
SUM(closing_balance) AS closing_balance
FROM
padded_combined
GROUP BY
month_year,
prod_id
ORDER BY
month_year,
prod_id

SQL group by count across two tables

I have got two tables called baseline and revisits
baseline
formid-------NoOfIssues
1--------------3
2--------------4
3--------------5
revisits
id------formid-------NoOfIssues-----------date--------------fid
1---------2--------------4-------------5/06/2016------------1
2---------3--------------3-------------15/06/2016-----------1
3---------1--------------4-------------20/07/2016-----------1
4---------1--------------3-------------25/07/2016-----------1
5---------2--------------5-------------28/07/2016-----------1
6---------1--------------5-------------01/06/2016-----------1
7---------3--------------8-------------21/02/2016-----------1
8---------3--------------2-------------21/02/2016-----------2
These tables are joined by 'formid'.
I need to compare number of issues in baseline vs revisits(only first) and get a count as reduced, increased or equal
Based upon the above table i am expecting the following, for example across all three baseline entries no equals were found comparing NoOfissues in first revisit against same formid, but 1 equal and 2 increased were found
Addition: if same date and same formid is found than take the lower fid, so in the last two rows of revisits table both formid and date are equal but need to consider the lower formid which is 1
status----------Count
reduced----------0
equal------------1
increased--------2
I'm not familiar with intersystems-cache, but you can see if the following is valid SQL with that DB:
SELECT
CASE
WHEN BL.NoOfIssues = FR.NoOfIssues THEN 'equal'
WHEN BL.NoOfIssues > FR.NoOfIssues THEN 'reduced'
WHEN BL.NoOfIssues < FR.NoOfIssues THEN 'increased'
END AS status,
COUNT(*) AS Count
FROM
Baseline BL
INNER JOIN Revisits FR ON FR.formid = BL.formid
LEFT OUTER JOIN Revisits R ON
R.formid = BL.formid AND
(
R.date < FR.date OR
(R.date = FR.date AND R.fid > FR.fid)
)
WHERE
R.formid IS NULL
GROUP BY
CASE
WHEN BL.NoOfIssues = FR.NoOfIssues THEN 'equal'
WHEN BL.NoOfIssues > FR.NoOfIssues THEN 'reduced'
WHEN BL.NoOfIssues < FR.NoOfIssues THEN 'increased'
END
Some quick notes on your database though - You should probably decide on a standard of plural or singular table names and stick with it. Also, try to avoid common reserved words for object names, like date. Finally, if a revisit is basically the same as a visit, just on a later date then you should consider keeping them all in the same table.
I would do this in one row rather than three:
select sum(case when numissues = rcnt then 1 else 0 end) as equal,
sum(case when numissues > rcnt then 1 else 0 end) as reduced,
sum(case when numissues < rcnt then 1 else 0 end) as incrased
from (select b.form_id, b.numissues, count(r.form_id) as rcnt
from baseline b left join
revisits r
on b.form_id = r.form_id
group by b.form_id, b.numissues
) br;
I would use a window function to get the number of ussues at the minimum date, then compare that to the baseline number of issues
select
case when baseline.NoOfIssues = rev.NoOfIssues then 'equal'
when baseline.NoOfIssues > rev.NoOfIssues then 'reduced'
when baseline.NoOfIssues < rev.NoOfIssues then 'increased'
end as status,
count(*) as count
from baseline
inner join(
select
formid,
case when date = min(date) over(partition by formid) then NoOfIssues else null end as first_rev_issues
from revisits
) rev
on baseline.formid = rev.formid
group by
case when baseline.NoOfIssues = rev.NoOfIssues then 'equal'
when baseline.NoOfIssues > rev.NoOfIssues then 'reduced'
when baseline.NoOfIssues < rev.NoOfIssues then 'increased'
end
Or like this:
WITH CTE AS
(
SELECT
BL.FORMID,
BL.NOOFISSUES AS BLI,
RV.NOOFISSUES AS RVI,
RV.DATE,
ROW_NUMBER() OVER(PARTITION BY BL.FORMID ORDER BY RV.DATE) AS RN
FROM Baseline BL
INNER JOIN Revisits RV ON RV.FORMID = BL.FORMID
)
SELECT COALESCE(SUM(CASE WHEN RVI > BLI THEN 1 END), 0) AS INCREASED,
COALESCE(SUM(CASE WHEN RVI < BLI THEN 1 END), 0) AS DECREASED,
COALESCE(SUM(CASE WHEN RVI = BLI THEN 1 END), 0) AS EQUAL
FROM CTE
WHERE RN=1;

How to aggregate and make a ratio between two fields from a CTE

I have a query which return a flag wheter a client who made a contract with my company this year is new or returning:
WITH Resultset AS(
SELECT
Cnt = COUNT(*)
,KliRC --personal identification number
FROM dbo.Smlouvy
WHERE VyplacenaCastka > 0
GROUP BY KliRC
)
SELECT
s.KliRC
,CASE WHEN Cnt > 1 THEN 1 ELSE 0 END AS Novy --new client
,CASE WHEN Cnt = 1 THEN 1 ELSE 0 END AS Stavajici --existing client
FROM Resultset JOIN dbo.Smlouvy s ON s.KliRC = resultset.KliRC
WHERE (YEAR(DatumZadosti) = YEAR(GETDATE())) AND (s.KliRC NOT LIKE '%x')
Now, I need to aggregate all the new and existing clients and make a ratio between them.
Any ideas? Thanks in advance.
I think this does what you want:
WITH Resultset AS (
SELECT COUNT(*) as cnt,
KliRC --personal identification number,
(CASE WHEN COUNT(*) > 1 THEN 1 ELSE 0 END) AS Novy --new client
(CASE WHEN COUNT(*) = 1 THEN 1 ELSE 0 END) AS Stavajici
FROM dbo.Smlouvy
WHERE VyplacenaCastka > 0
GROUP BY KliRC
)
SELECT SUM(Novy) / SUM(Stavajici)
FROM Resultset r JOIN
dbo.Smlouvy s
ON s.KliRC = r.KliRC
WHERE YEAR(DatumZadosti) = YEAR(GETDATE()) AND
s.KliRC NOT LIKE '%x';
Your query can be simplified to
SELECT SUM(Novy)*1.0/SUM(Stavajici)
FROM (
SELECT KliRC
,CASE WHEN COUNT(*) OVER(PARTITION BY KliRC) > 1 THEN 1 ELSE 0 END AS Novy --new client
,CASE WHEN COUNT(*) OVER(PARTITION BY KliRC) = 1 THEN 1 ELSE 0 END AS Stavajici --existing client
FROM dbo.Smlouvy
WHERE YEAR(DatumZadosti) = YEAR(GETDATE()) AND KliRC NOT LIKE '%x'
) T

Select with subquery select not working

I keep getting that error on this code. I am not using EXISTS.Please Help.
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
SQL:
If ISDATE(#grpsearch) = 1
SELECT grp.GroupID,
vlanlist.InternetType,
grp.GroupName, cast(grp.StartDateTime as date) as StartDate,
convert(varchar,cast(grp.StartDateTime as time),100) as starttime,
(select case when datepart(hh,convert(datetime,grp.StartDateTime)) > 12 then datepart(hh,convert(datetime,grp.StartDateTime))-12
else case when datepart(hh,convert(datetime,grp.StartDateTime)) = 0 then '12' else datepart(hh,convert(datetime,grp.StartDateTime)) end end as starthour,
datepart(mi,convert(datetime,grp.StartDateTime)) as startmin, case when datepart(hh,convert(datetime,grp.StartDateTime)) >= 12 then 'PM' else 'AM' end as startperiod),
cast(grp.enddatetime as date) as EndDate,
convert(varchar,cast(grp.EndDateTime as time),100) as EndTime,
grp.UserInitials,
grp.UserComments,
roomlist.RoomName,
jacklist.JackNumber
FROM a_Cisco.dbo.grp_internet as grp left outer join
dbo.jacklist as jacklist ON grp.intJack = jacklist.intJack left outer join
dbo.roomlist as roomlist ON grp.intRoom = roomlist.intROom left outer join
dbo.vlanlist as vlanlist ON grp.VlanID = vlanlist.VlanID
WHERE (convert(varchar,cast(grp.StartDateTime as date),100) = #grpsearch)
The problem is this part of the query:
(select case when datepart(hh,convert(datetime,grp.StartDateTime)) > 12
then datepart(hh,convert(datetime,grp.StartDateTime))-12
else case when datepart(hh,convert(datetime,grp.StartDateTime)) = 0
then '12' else datepart(hh,convert(datetime,grp.StartDateTime))
end
end as starthour,
First, you don't need the select at all. Second, you are missing the closing parentheses ()). I would suggest:
(case when datepart(hh,convert(datetime,grp.StartDateTime)) > 12
then datepart(hh,convert(datetime,grp.StartDateTime))-12
else (case when datepart(hh,convert(datetime,grp.StartDateTime)) = 0
then '12'
else datepart(hh,convert(datetime,grp.StartDateTime))
end)
end) as starthour,