Oracle query - how to make count to return values with 0 - sql

How can I make a count to return also the values with 0 in it.
Example:
select count(1), equipment_name
from alarms.new_alarms
where equipment_name in (
select eqp from ne_db.ne_list)
Group by equipment_name
It is returning only the counts with values higher than 0 , but I need to know the records that are not returning anything.
Any help is greatly appreciated.
thanks,
Marco

Try using LEFT JOIN,
SELECT a.eqp, COUNT(b.equipment_name) totalCount
FROM ne_db.ne_list a
LEFT JOIN alarms.new_alarms b
ON a.eqp = b.equipment_name
GROUP BY a.eqp

If the table ne_list has no duplicates, then you can do a left join. That assumption may not be true, so the safest way to convert this is by removing duplicates in a subquery:
select count(1), ne.equipment_name
from alarms.new_alarms ne left outer join
(select distinct eqp
from ne_db.ne_list
) eqp
on ne.equipment_name = eqp.eqp
Group by ne.equipment_name

You could use a left join:
select ne.equipment_name
, count(na.equipment_name)
from ne_db.ne_list ne
left join
alarms.new_alarms na
on ne.eqp = na.equipment_name
group by
ne.equipment_name

This should work too
(select equipment_name, count(*) as cnt from alarms.new_alarms
where equipment_name in (
select eqp from ne_db.ne_list
) group by equipment_name
)union(
select equipment_name, 0 as cnt from alarms.new_alarms
where equipment_name not in (
select eqp from ne_db.ne_list
) group by equipment_name
) order by equipment_name

Related

How to fix "ABAP INNER JOIN"

i'm trying to get a inner join from two select sentences but it doesn't work, what i am doing wrong?
i cant work with internal tables because inner join doesn't permit it.
clear: it_spfli.
refresh: it_spfli.
select
spfli-cityto
spfli-cityfrom
into TABLE it_spfli from(select spfli-cityto COUNT( * )from spfli group by spfli-cityto) as t1
INNER JOIN(select spfli-cityfrom COUNT( * )from spfli group by spfli-cityfrom) as t2
ON t1-cityto = t2-cityfrom.
i expect a table of more frequency city to and city from order by city to with table spfli.
First of all i don't think you are doing the right SELECT to get what you want.
I answer this question from the technical perspective. You can use WITH.
WITH +spf1 AS (
SELECT spfli~cityto AS cityto, COUNT(*) AS count FROM spfli GROUP BY spfli~cityto ) ,
+spf2 AS (
SELECT spfli~cityfrom AS cityfrom , COUNT(*) AS count FROM spfli GROUP BY spfli~cityfrom ) ,
+spf3 AS (
SELECT s1~cityto, s2~cityfrom FROM +spf1 AS s1 INNER JOIN +spf2 AS s2
ON s1~cityto = s2~cityfrom )
SELECT * FROM +spf3 INTO TABLE #DATA(lt_result).

Nested Subqueries with Group By

Having trouble with this one. Getting syntax error at the arrow. I'm using subqueries on purpose. I'm wondering if it's possible to mix 'where' and 'having'?
;with books_not_ordered as
(
select BK.book_id
from bkinfo.books BK
where BK.book_id not in
(
select OD.book_id
from bkorders.order_details OD
)
)
select AU.author_id, AU.author_name_last
from bkinfo.authors AU
where exists
(
select BAU.author_id, count(*) as NumBooks
from bkinfo.book_authors BAU
group by BAU.author_id
having count(*) > 1
==>where AU.author_id = BAU.author_id
and
BAU.book_id in
(
select BK.book_id
from bkinfo.books BK
where BK.book_id in
(
select cte.book_id
from books_not_ordered cte
)
)
)
;
go
The where clause should come before your group by and having
select BAU.author_id, count(*) as NumBooks
from bkinfo.book_authors BAU
where AU.author_id = BAU.author_id
group by BAU.author_id
having count(*) > 1
Assuming that you are trying to get "The authors of the books that are not in order_details table, but who have written more than one book". The following query should work.
SELECT AU.author_id, AU.author_name_last
FROM bkinfo.books BK
JOIN bkinfo.book_authors BAU ON BAU.author_id = BK.author_id
JOIN bkinfo.authors AU ON BAU.author_id = AU.author_id
LEFT OUTER JOIN bkorders.order_details OD ON BK.book_id = OD.book_id
WHERE OD.book_id IS NULL
GROUP BY AU.author_id, AU.author_name_last
HAVING COUNT(BK.Book_id) > 1

Complex Full Outer Join

Sigh ... can anyone help? In the SQL query below, the results I get are incorrect. There are three (3) labor records in [LaborDetail]
Hours / Cost
2.75 / 50.88
2.00 / 74.00
1.25 / 34.69
There are two (2) material records in [WorkOrderInventory]
Material Cost
42.75
35.94
The issue is that the query incorrectly returns the following:
sFunction cntWO sumLaborHours sumLaborCost sumMaterialCost
ROBOT HARNESS 1 12 319.14 236.07
What am I doing wrong in the query that is causing the sums to be multiplied? The correct values are sumLaborHours = 6, sumLaborCost = 159.57, and sumMaterialCost = 78.69. Thank you for your help.
SELECT CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END AS sFunction,
(SELECT COUNT(*)
FROM work_orders
FULL OUTER JOIN Work_Orders_Archived
ON work_orders.order_number = Work_Orders_Archived.order_number
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630') AS cntWO,
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
FROM work_orders
FULL OUTER JOIN Work_Orders_Archived
ON work_orders.order_number = Work_Orders_Archived.order_number
LEFT OUTER JOIN
(SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
FROM LaborDetail) AS LD
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
LEFT OUTER JOIN
(SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
FROM WorkOrderInventory) AS WOI
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630'
GROUP BY CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END
ORDER BY sFunction
Try using the SUM function inside a derived table subquery when doing the full join to "WorkOrderInventory" like so...
select
...
sum(hrs) as sumlaborhrs,
sum(cost) as sumlaborcost,
-- calculate material cost in subquery
summaterialcost
from labordetail a
full outer join
(select ordernumber, sum(materialcost) as summaterialcost
from WorkOrderInventory
group by ordernumber
) b on a.workorderno = b.ordernumber
i created a simple sql fiddle to demonstrate this (i simplified your query for examples sake)
Looks to me that work_orders and work_orders_archived contains the same thing and you need both tables as if they were one table. So you could instead of joining create a UNION and use it as if it was one table:
select location as sfunction
from
(select location
from work_orders
union location
from work_orders_archived)
Then you use it to join the rest. What DBMS are you on? You could use WITH. But this does not exist on MYSQL.
with wo as
(select location as sfunction, order_number
from work_orders
union location, order_number
from work_orders_archived)
select sfunction,
count(*)
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
from wo
LEFT OUTER JOIN
(SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
FROM LaborDetail) AS LD
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
LEFT OUTER JOIN
(SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
FROM WorkOrderInventory) AS WOI
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
where wo.order_number = '919630'
group by sfunction
order by sfunction
The best guess is that the work orders appear more than once in one of the tables. Try these queries to check for duplicates in the two most obvious candidate tables:
select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
from work_orders
group by order_number
) t
group by cnt
order by 1;
select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
from work_orders_archived
group by order_number
) t
group by cnt
order by 1;
If either returns a row where cnt is not 1, then you have duplicates in the tables.

Grabbing Details of Customers who appear more than once

I'm getting a strange error with the below code. No column was specified for column 2 of 'no1'.
As far as I can tell it should work. I'm simply trying to get a collection of details about customers where the customers exist more than once on the receipts tbl.
SELECT
CM.ClientID,
CPN.Birthdate,
CM.ClientPassword
FROM
dbo.ClientMaster AS CM
JOIN dbo.ClientPerson AS CPN ON (CM.ClientID = CPN.ClientID)
JOIN dbo.ClientProduct AS CP ON (CPN.ClientID = CP.ClientID)
WHERE
CM.ClientID IN (
SELECT
no1.ClientID
FROM
(
SELECT
CM.ClientID,
COUNT(*)
FROM
dbo.ClientMaster AS CM
JOIN dbo.ClientPerson AS CPN ON (CM.ClientID = CPN.ClientID)
JOIN dbo.ClientProduct AS CP ON (CPN.ClientID = CP.ClientID)
WHERE
CP.PolicyNo IN (SELECT PolicyNo FROM Receipts)
AND CM.ClientID IS NOT NULL
AND Birthdate IS NOT NULL
AND ClientPassword IS NOT NULL
GROUP BY
CM.ClientID
HAVING
COUNT(*)>1
) AS no1
)
SOLUTION
Ah did not realise you don't need the Count(*) in the Select. Thanks guys!
This is what I ended up going with.
SELECT DISTINCT
CM.ClientID,
CPN.Birthdate,
CM.ClientPassword
FROM
dbo.ClientMaster AS CM
JOIN dbo.ClientPerson AS CPN ON (CM.ClientID = CPN.ClientID)
JOIN dbo.ClientProduct AS CP ON (CPN.ClientID = CP.ClientID)
WHERE
CM.ClientID IN (
SELECT
ClientID
FROM
Receipts
GROUP BY
ClientID
HAVING
COUNT(*)>1
)
AND CM.ClientID IS NOT NULL
AND Birthdate IS NOT NULL
AND ClientPassword IS NOT NULL
Your COUNT(*) column needs a name, like:
COUNT(*) AS RecordCount
You don't need to nest the same query twice for that. You can do this instead:
SELECT
CM.ClientID,
CPN.Birthdate,
CM.ClientPassword
FROM
dbo.ClientMaster AS CM
JOIN dbo.ClientPerson AS CPN ON (CM.ClientID = CPN.ClientID)
JOIN dbo.ClientProduct AS CP ON (CPN.ClientID = CP.ClientID)
GROUP BY CM.ClientID, CPN.Birthdate, CM.ClientPassword
HAVING COUNT(CM.ClientID) > 1

how to get the count in SQL Server?

I have tried a lot to figure how to get the count from two tables with respect to master table
I have three tables
Using these table values I need to get this output..
Tried but could get the desired result
http://en.wikipedia.org/wiki/Join_(SQL)
SQL - LEFT OUTER JOIN and WHERE clause
http://forums.devshed.com/oracle-development-96/combination-of-left-outer-join-and-where-clause-383248.html
You have to first GROUP BY in subqueries, then JOIN to the main table:
SELECT
a.AttributeId
, COALECSE(cntE, 0) AS cntE
, COALECSE(cntM, 0) AS cntM
FROM
AttributeMaster AS a
LEFT JOIN
( SELECT
AttributeId
, COUNT(*) AS cntE
FROM
EmployeeMaster
GROUP BY
AttributeId
) em
ON em.AttributeId = a.AttributeId
LEFT JOIN
( SELECT
AttributeId
, COUNT(*) AS cntM
FROM
MonthlyDerivedMaster
GROUP BY
AttributeId
) mdm
ON mdm.AttributeId = a.AttributeId
SELECT AttributeId,
(SELECT COUNT(Eid) FROM EmployeeMaster WHERE AttributeMaster.AttributeId = EmployeeMaster.AttributeId) as master_eid,
(SELECT COUNT(Eid) FROM MonthnlyDerivedMaster WHERE AttributeMaster.AttributeId = MonthnlyDerivedMaster.AttributeId) as monthly_eid
FROM AttributeMaster