Loop Back to Same Table - sql

Is there a way to combine these two queries into a single query - just one trip to the database?
Both queries hit the same table, but the first is looking for Total Active Circuits, while the second is looking for Total Circuits.
I am hoping to display results like this...
4/15, 12/34, 2/21 (where the first number is ActiveCircuits and the second number is TotalCircuits)
SELECT COUNT(CircuitID) AS ActiveCircuits
FROM Circuit
WHERE StateID = 5
AND Active = 1
SELECT COUNT(CircuitID) AS TotalCircuits
FROM Circuit
WHERE StateID = 5

Use conditional aggregation:
SELECT COUNT(*) AS TotalCircuits,
SUM(CASE WHEN Active = 1 THEN 1 ELSE 0 END) as ActiveCircuits
FROM Circuit
WHERE StateID = 5;
This assumes that CircuitId is never NULL, which seems quite reasonable in a table called Circuit.

You can use case when to have a 1 wherever it's active and then take the sum to get the total # of 1's or activecircuits.
SELECT COUNT(CIRCUITID) AS TOTALCIRCUITS,
SUM(CASE WHEN ACTIVE = 1 THEN 1 ELSE 0 END) AS ACTIVECIRCUITS
FROM CIRCUIT
WHERE STATEID = 5

Related

Complex SQL query to combine rows

I have 2 tables first is
Thread { code, itr_global,campaign, contact, start_time,duration}
segment {code,thread,start_time,duration,state}
There are multiple other joins but these 2 are major joins. 2 table are realted as thread.code=segment.thread.
In segment table there will be multiple rows for singl thread. I need to get values
campaign start_time duration waititme talk_time hold_time wrap_time
Where wait_time I can get as segment.state=7 & talke_time=segment.state=6 & wrap time as segment.state=8
I am not able to get all these values in single row as it will give me 3 diffrent rows for each record. How can I get all the values in single row as per above format.
You need some conditional aggregation SUM(CASE...) to get the result you want.
All this is based on my guesses about the structure and meaning of your tables, which you omitted from your question.
SELECT thread.code, thread.campaign,
SUM(segment.duration) duration,
SUM(CASE WHEN segment.state = 7 THEN segment.duration END) waittime,
SUM(CASE WHEN segment.state = 6 THEN segment.duration END) talk_time,
SUM(CASE WHEN segment.state = 8 THEN segment.duration END) wrap_time,
42 hold_time, -- you didn't say how to get hold_time
SUM(CASE WHEN segment.state = 8 THEN segment.duration END) wrap_time
FROM Thread
LEFT JOIN segment ON Thread.code = segment.thread
GROUP BY thread.code, thread.campaign

How do I select this grouped data correctly?

First of all, sorry for the generic title, I don't know how exactly to word the question I have.
I am working with a legacy database and can't make changes to the schema, so I'm forced to work with what I've got.
Table setup (columns):
Id (a normal int id)
UniqueId (a column that holds the uniqueIds for each location)
status (a varchar column that can contain one of three status's, 'completed', 'failed', 'Attention')
Count (an int column that represents how many users fell into each status
Example data :
UniqueId Status Count
679FCE83-B245-E511-A42C-90B11C2CD708 completed 64
679FCE83-B245-E511-A42C-90B11C2CD708 Attention 1
679FCE83-B245-E511-A42C-90B11C2CD708 failed 101
4500990D-F516-E411-BB09-90B11C2CD708 completed 100
4500990D-F516-E411-BB09-90B11C2CD708 Attention 17
4500990D-F516-E411-BB09-90B11C2CD708 failed 516
557857BD-6B46-E511-A42C-90B11C2CD708 completed 67
557857BD-6B46-E511-A42C-90B11C2CD708 Attention 4
557857BD-6B46-E511-A42C-90B11C2CD708 failed 103
What I am trying to do is select all of the records, grouped by uniqueId, with a separate column for each of the status's containing their individual counts. The results would look something like this...
UniqueId, count(completed), count(failed), count(Attention)
679FCE83-B245-E511-A42C-90B11C2CD708 64 101 1
4500990D-F516-E411-BB09-90B11C2CD708 100 516 17
557857BD-6B46-E511-A42C-90B11C2CD708 67 103 4
I'm sure I'm missing something basic with this, but I can't seem to find the words to Google my way out of this one.
Could someone push me in the right direction?
You can use conditional aggregation:
select uniqueid,
sum(case when status = 'Completed' then count else 0 end) as completed,
sum(case when status = 'Failed' then count else 0 end) as failed,
sum(case when status = 'Attention' then count else 0 end) as attention
from t
group by uniqueid;

SQL SSMS 2017 Detailed result

I´m a bit newbie to SQL, so I want to ask for possible solution how to create a query which will show the desired results.
There´s a table where are the data coming continuously from one main PLC so everything is gathered in 1 table. There are a bunch of data per 1 shift (about half million). In column "Op" are the machines represented by their IDs (Op = ID of machine). Machines are about from 1 to 218. Every machine has it´s their cycle times divided into starting process (T1), duration (T2), end process(T3) and Result. The "Result" can be interpreted as 0 - as OK, 1 - not OK, 2 - empty pallet, 3 - free flow of pallet. Those are the Results of what the PLCs are reporting directly into database´s table.
I have tried the basic statements to count these results for exact record states (0,1,2,3) and for exact machine. That´s OK but not the desired goal.
SELECT Count(*) as Result0
FROM PalletOperations
where Op = 1 and Result = 0
The expected result is to show a full list of every machines from 1 to 218 how many results were counted as 0, 1, 2 and 3. The other columns are not relevant for this time. The main goal is to show a result as every machine has its own row with the expected data of counted states result. If theres 218 machines, than I need to generate results of 218 machines separately from 1 to 218 in rows. Each row should contain the Op(name 1,2,3,4....218) with the columns of counted result for states 0,1,2,3 as mentioned above.
Any advice is welcome
I think you want conditional aggregation:
SELECT op,
SUM(CASE WHEN Result = 0 THEN 1 ELSE 0 END) as result_0,
SUM(CASE WHEN Result = 1 THEN 1 ELSE 0 END) as result_1,
SUM(CASE WHEN Result = 2 THEN 1 ELSE 0 END) as result_2,
SUM(CASE WHEN Result = 3 THEN 1 ELSE 0 END) as result_3
FROM PalletOperations
GROUP BY op;
you can use the below sql statement to get count of results per machine per result
SELECT op,Result, count(*)
FROM PalletOperations
GROUP BY op,Result;

Count where conditions are different

I've been trying to optimize one of my more bulky db views.
Presently, I'm just using sub-selects 5 times to get the count of the company ID's.
(Select count(id) from company table where prospecting.stage = 'qualify') as Qualify,
(Select count(id) from company table where prospecting.stage = 'targetted') as Targetted,
Each company goes through 5 stages, I simply want to count the amount of companies in each stage by company location in separate columns.
I'm trying to do this in one select, but I am getting a bit stuck.
SUM(COUNT(CASE WHEN prospecting.stage = 'Qualify' THEN '1' ELSE '0' END)) as [Qualified]
SUM(COUNT(CASE WHEN prospecting.stage = 'Targetted' THEN '1' ELSE '0' END)) as [Targetted]
So it ends up looking something along these lines:
Location | Stage: Qualify | Stage: Targetted | Stage 3 | Stage 4 | Stage 5 | Total
Cannot perform an aggregate function on an expression containing an aggregate or a subquery. -Makes sense.
So I need to count the Company.ID where the prospecting.stage = 'XYZ' into separate rows per stage.
Any advice? :(
Drop the count function and change the datatype from char to int in the case expressions. Your expressions should look like this:
SUM(CASE WHEN prospecting.stage = 'Qualify' THEN 1 ELSE 0 END) as [Qualified]

Change the value of a sum in sql

I'm doing a query to obtain the numbers of people for a Christmas dinner.
The people include the workers and their relatives. The relatives are stored in a different table.
Children and adults eat a different menu and we organize tables by families.
I'm already using this query
select worker_name,
count(*) as total_per_family,
SUM(CASE WHEN age < 18 THEN 1 ELSE 0 END) as children,
SUM(CASE WHEN age >= 18 THEN 1 ELSE 0 END) as adults
from
(
/*subquery*/
)
group by worker_name
order by worker_name;
This query returns the number of child and adults related to the worker and count gives me the total.
The problem is that I need to add the worker to the adults sum.
Is there a way to modify adults? Either setting its initial value to 1 or adding 1 after the sum is done but before the count is obtained.
Modifying your query to read
SUM(CASE WHEN AGE>=18 THEN 1 ELSE 0 END) + 1 as adults
would probably be a first approach. The aggregate SUM() would be computed first, with 1 added thereafter as your initial suggestion indicated.