SQL - how to SUM two Count Statements to create a Total Column - sql

i have the following query and for the life of me have forgotton how to SUM both columns to create a 'Total' column
SELECT username as 'username',
count (case when casestype <> 'car'
OR casestype <> 'van'
OR casestype <> 'bike'
OR casestype <> 'NONE'
THEN 1 ELSE NULL END) as 'non-auto',
count (case when casestype = 'car'
OR casestype= 'van'
OR casestype = 'bike'
THEN 1 ELSE NULL END) as 'auto'
FROM Case WITH (NOLOCK)
WHERE CaseDate BETWEEN '01 may 2016' AND '31 may 2016')
GROUP BY username
I want to have a total column of non-auto + auto

SELECT username,
sum(case when casestype not in ('car', 'van', 'bike', 'NONE')
then 1 else 0
end) as non_auto,
sum(case when casestype in ('car', 'ban', 'bike') then 1 else 0
end) as auto,
sum(case when casestype <> 'NONE' then 1 else 0 end) as total
FROM [Case]
WHERE CaseDate BETWEEN '2016-05-01' and '2016-05-31'
GROUP BY username;
Additional advice:
in and not in are much more readable than a series of or statements.
Use ISO standard date formats. YYYY-MM-DD is my preference, although SQL Server has a slight preference for YYYYMMDD.
The total needs to be calculated separately. If you want to use column aliases you need subqueries or CTEs.
Don't use single quotes for column aliases. Only use them for string and date constants.

Related

SQL Query to Combine rows

I have a query that currently prints out what I need but doesn't combine the rows that I need. For example, I need the first two rows with the meter name to be combined together and so on for the rest of the meter names.
This is currently what I have:
SELECT
--Displays Client Number
CASE
WHEN v.MID IS NULL THEN ''
ELSE v.ClientNumber
END AS 'Client Number',
--Displays MID Number
CASE
WHEN v.MID IS NULL THEN ''
ELSE v.MID
END AS MID,
--Displays Meter Name
CASE
WHEN v.MID IS NULL THEN ''
ELSE v.MeterName
END AS 'Meter Name',
/*
CASE
WHEN v.MID IS NULL THEN 0
ELSE SUM(v.MCF)
END AS MCF,
*/
--Displays January's MCF
CASE
WHEN v.AccountPeriod = '2018-01-01' THEN SUM(v.MCF)
ELSE 0
END AS January,
--Displays Febuary's MCF
CASE
WHEN v.AccountPeriod = '2018-02-01' THEN SUM(v.MCF)
ELSE 0
END AS Febuary,
CASE
WHEN v.MID IS NULL THEN 0
ELSE SUM(v.mcf)
END AS 'Meter Total'
FROM Volumes v
LEFT JOIN CurrentMeters cm
ON v.MID = cm.MID
WHERE cm.ClientNumber = 107500
GROUP BY v.MID, v.AccountPeriod, v.ClientNumber, v
Does anyone have any suggestions as to what I should do or how I should approach this?
I think you just want conditional aggregation:
SELECT (CASE WHEN v.MID IS NULL THEN '' ELSE v.ClientNumber END) AS Client_Number,
COALESCE(WHEN v.MID, '') as MID,
(CASE WHEN v.MID IS NULL THEN '' ELSE v.MeterName END) AS Meter_Name,
SUM((CASE WHEN v.MID IS NULL THEN 0 v.MCF END) AS MCF,
SUM(CASE WHEN v.AccountPeriod = '2018-01-01' THEN v.MCF ELSE 0 END) AS January,
SUM(CASE WHEN v.AccountPeriod = '2018-02-01' THEN v.MCF ELSE 0 END) AS January,
SUM(CASE WHEN v.MID IS NULL THEN 0 ELSE v.mcf END) AS Meter_Total
FROM Volumes v JOIN
CurrentMeters cm
ON v.MID = cm.MID
WHERE cm.ClientNumber = 107500
GROUP BY (CASE WHEN v.MID IS NULL THEN '' ELSE v.ClientNumber END),
COALESCE(WHEN v.MID, ''),
(CASE WHEN v.MID IS NULL THEN '' ELSE v.MeterName END);
Notes:
Your WHERE clause is turning the outer join into an inner join, so there is no reason to express an outer join.
The GROUP BY keys specify what defines a row in the result set. Each combination of unique values in the data is in exactly one row. Hence, you don't want AccountPeriod in the GROUP BY.
Presumably, you want one row for each of the expressions that define a row, so these expressions are in the group by.
For conditional aggregation, the CASE expression is an argument to an aggregation function such as SUM().

Group by in sql for two conditions

I have this table
SELECT
[WeldStatus]
,PackageId
FROM [SPMS2].[dbo].[JointHistory]
How can I group by this query to calculate total testpackage and total accept and total remain?
For example for packageid=6030 I need this:
packageid total accept remain
6030 4 3 1
Use CASE and Group By
SELECT
PackageId,
count(*) as total,
sum(case [WeldStatus] when 'Accept' then 1 end) as accept,
sum(case [WeldStatus] when 'accept' then 0 else 1 end) as remain
FROM [SPMS2].[dbo].[JointHistory]
group by PackageId;
SELECT
packageid
,count(*) as 'total'
,sum(case when weldstatus = 'Accept' then 1 else 0 end) as 'accept'
,sum(case when weldstatus is null then 1 else 0 end) as 'remain'
FROM [SPMS2].[dbo].[JointHistory]
group by packageid
"sum(case when..." has saved me so many times. NULLs can be a pain but the case when saves you.
You can use CASE expression with in your aggregation to achieve your desired output.
SELECT
PackageId,
SUM (CASE WHEN WeldStatus = 'Accept' THEN 1 ELSE 0 END) AS AcceptCount,
SUM (CASE WHEN WeldStatus IS NULL THEN 1 ELSE 0 END) AS RemainCount,
COUNT (*) AS Total
FROM [SPMS2].[dbo].[JointHistory]
GROUP BY PackageId
select packageid, SUM(TOTAL), SUM(ACCEPT), SUM(REMAIN) from (
select packageid, 1 as TOTAL,
case
when WeldStatus='Accept' then 1 else 0
END as ACCEPT,
case
when WeldStatus IS NULL then 1 else 0
END as REMAIN
from JointHistory
) group by packageid
If WeldStatus only takes on the values of 'Accept' or NULL, then a simple method is:
SELECT PackageId, count(*) as total,
count(WeldStatus) as accept,
count(*) - count(WeldStatus) as remain
FROM [SPMS2].[dbo].[JointHistory] jh
GROUP BY PackageId;
I'm the first to admit that this relies on the assumption of having a single value or NULL.
SELECT PackageId,
COUNT(*) AS total,
SUM(CASE WHEN [WeldStatus] = 'Accept' THEN 1 END) AS accept,
SUM(CASE WHEN ISNULL([WeldStatus],'') = '' THEN 1 ELSE 0 END) AS remain
FROM [SPMS2].[dbo].[JointHistory]
group by PackageId;

Same part of a subquery in multiple select

I have a table like this
TABLEMAIN
Q1 Name Group Zone Month Type
1 'N1' 'G1' 'Z1' 12 'T1'
4 'N1' 'G3' 'Z2' 12 'T6'
6 'N1' 'G1' 'Z5' 12 'T2'
3 'N2' 'G4' 'Z5' 12 'T4'
.
.
.
And I have something like this to get certain results
Query1:
select
(SUM(CASE Q1>=2 and Q1<=4 THEN 1 ELSE 0 END)) TOTAL,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) T1TYPE,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) T2TYPE,
Type,
**Zone,**
Month
from
TABLEMAIN
GROUP BY Type, **Zone,** Month;
Query2:
select
(SUM(CASE Q1>=2 and Q1<=4 THEN 1 ELSE 0 END)) TOTAL,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) T1TYPE,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) T2TYPE,
Type,
**Group,**
Month
from
TABLEMAIN
GROUP BY Type, **Group,** Month;
As you can see I group this table many times in many ways, but this part is the same in every query
select
(SUM(CASE Q1>=2 and Q1<=4 THEN 1 ELSE 0 END)) TOTAL,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) T1TYPE,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) T2TYPE,
Is there a better way to do this? I'm not sure if I can use a materialized view for this
Perhaps. You can do it all in one query, if you like by using grouping sets:
select SUM(CASE Q1>=2 and Q1<=4 THEN 1 ELSE 0 END) as TOTAL,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) as T1TYPE,
(CASE WHEN Type = 'T1' THEN SUM(CASE WHEN Q1=4 THEN 1 ELSE 0 END)) as T2TYPE
Type, **Zone,**, **Group,** Month
from TABLEMAIN
GROUP BY GROUPING SETS((Type, **Zone,** Month), (Type, **Group,** Month));
This puts all the results in a single table.
I second with #GolezTrol comment. Would like to explain further.
SUBQUERY FACTORING is what you need. The WITH clause, or subquery factoring clause, is part of the SQL-99 standard and was added into the Oracle SQL syntax in Oracle 9.2. The WITH clause may be processed as an inline view or resolved as a temporary table. The advantage of the latter is that repeated references to the subquery may be more efficient as the data is easily retrieved from the temporary table, rather than being required by each reference.
WITH data AS(
<your subquery>
)
SELECT * FROM data
bla bla bla...

translate aggregate SQL query with case and When to MS Access

I have executed with no problem the query in SQL but it does not work in Access
Case is not avaliable in Access right, so IIf must be used...
select
sum(case when date between '2012-05-01' AND '2012-06-01' then value else 0 end) as sum1,
sum(case when date between '2012-05-01' AND '2012-10-01' then value else 0 end) as sum2,
sum(case when situation like 'Urgent' then 1 else 0 end) as urgent,
sum(case when situation like 'Anual' then 1 else 0 end) as anual,
sum(1) as total
from mytable
Is there a better way of doing this?
Will this query work?
select
sum(IIf date between '2012-05-01' AND '2012-06-01',value,0) as sum1,
sum(IIf date between '2012-05-01' AND '2012-10-01',value,0) as sum2,
sum(IIf situation like 'Urgent',1,0 ) as urgent,
sum(IIf situation like 'Anual' ,1,0 ) as anual,
sum(1) as total
from mytable
You need parentheses for IIf() as in IIf(expression, truepart, falsepart)
Enclose date and value in square brackets because both are reserved words.
Your Like comparisons didn't include any pattern matching, so I substituted = instead.
I assumed date is Date/Time data type, so enclosed the values with the # delimiter.
SELECT
Sum(IIf([date] BETWEEN #2012-05-01# AND #2012-06-01#,[value],0)) AS Sum1,
Sum(IIf([date] BETWEEN #2012-05-01# AND #2012-10-01#,[value],0)) AS Sum2,
Sum(IIf(situation = 'Urgent',1,0 )) AS urgent,
Sum(IIf(situation = 'Anual' ,1,0 )) AS anual,
Sum(1) AS total
FROM mytable;

Merging data SQL Query

I have a query request where I have to show one customer activity for each web-site but it has to be only one row each, instead of one customer showing multiple times for each activity.
Following is the query I tried but brings lot more rows. please help me as how I can avoid duplicates and show only one customer by each row for each activity.
SELECT i.customer_id, i.SEGMENT AS Pistachio_segment,
(CASE when S.SUBSCRIPTION_TYPE = '5' then 'Y' else 'N' end ) PB_SUBS
(CASE WHEN S.SUBSCRIPTION_TYPE ='12' THEN 'Y' ELSE 'N' END) Daily_test,
(CASE when S.SUBSCRIPTION_TYPE ='8' then 'Y' else 'N' end) COOK_4_2
FROM IDEN_WITH_MAIL_ID i JOIN CUSTOMER_SUBSCRIPTION_FCT S
ON I.IDENTITY_ID = S.IDENTITY_ID and I.CUSTOMER_ID = S.CUSTOMER_ID
WHERE s.site_code ='PB' and s.subscription_end_date is null
Sounds like you need to group by customer_id and perform aggregations for the other columns you are selecting. For example:
sum(case when s.subscription_type = '5' then 1 else 0 end) as pb_subs_count
You could try one of two things:
Use a GROUP BY statement to combine all records with the same id, e.g.,
...
WHERE s.site_code ='PB' and s.subscription_end_date is null
GROUP BY i.customer_id
Use the DISTINCT command in your SELECT, e.g.,
SELECT DISTINCT i.customer_id, i.SEGMENT, ...
you could use a aggregation (SUM) on customer_id, but what do you expect to happen on the other fields? for example, if you have SUBSCRIPTION_TYPE 5 and 13 for the same customer (2 rows), which value do you want?
Perhaps you are looking for something like this:
SELECT i.customer_id, i.SEGMENT AS Pistachio_segment,
MAX(CASE when S.SUBSCRIPTION_TYPE = '5' then 'Y' else 'N' end ) PB_SUBS
MAX(CASE WHEN S.SUBSCRIPTION_TYPE ='12' THEN 'Y' ELSE 'N' END) Daily_test,
MAX(CASE when S.SUBSCRIPTION_TYPE ='8' then 'Y' else 'N' end) COOK_4_2
FROM IDEN_WITH_MAIL_ID i JOIN CUSTOMER_SUBSCRIPTION_FCT S
ON I.IDENTITY_ID = S.IDENTITY_ID and I.CUSTOMER_ID = S.CUSTOMER_ID
WHERE s.site_code ='PB' and s.subscription_end_date is null
GROUP BY i.customer_id, i.SEGMENT
I can't be sure, though, without knowing more about the tables involved.