MS SQL count values for per row for per id - sql

I'm trying to count incident types per depot. My current query returns the following result set:
I then apply a count query on this set which looks like this:
select middleList.DepotName as depot,
count(middleList.NearMiss) as NearMiss,
count(middleList.Theft) as Theft,
count(middleList.Security) as Security,
count(middleList.LostTimeDisablingInjury) as LostTimeDisablingInjury,
count(middleList.Fire) as Fire,
count(middleList.OccupationalIllness) as OccupationalIllness,
count(middleList.VehicleAccident) as LostTimeDisablingInjury,
count(middleList.Spliiage) as Fire,
count(middleList.PropertyDamage) as OccupationalIllness,
count(middleList.NonConformance) as NonConformance,
count(middleList.Other) as Other
from
(SELECT dbo.IncidentTypes.NearMiss, dbo.IncidentTypes.Theft,
dbo.IncidentTypes.Security, dbo.IncidentTypes.LostTimeDisablingInjury,
dbo.IncidentTypes.Fire, dbo.IncidentTypes.OccupationalIllness,
dbo.IncidentTypes.VehicleAccident, dbo.IncidentTypes.Spliiage,
dbo.IncidentTypes.PropertyDamage, dbo.IncidentTypes.NonConformance,
dbo.IncidentTypes.Other, dbo.Incidents.IncidentTitle, dbo.Depots.DepotName,
dbo.Incidents.IncidentNumber
FROM dbo.Departments INNER JOIN
dbo.Depots ON dbo.Departments.DepotId = dbo.Depots.DepotId
INNER JOIN
dbo.Employees ON dbo.Departments.DepartmentId =
dbo.Employees.DepartmentId INNER JOIN
dbo.IncidentTypes INNER JOIN
dbo.Incidents ON dbo.IncidentTypes.IncidentTypeId =
dbo.Incidents.IncidentTypeId ON dbo.Employees.EmployeeId =
dbo.Incidents.EmployeeId_EmployeeInvolv
Where Incidents.DateCreated = (SELECT MAX (i2.DateCreated) FROM
Incidents as i2 WHERE Incidents.IncidentNumber = i2.IncidentNumber)) as
middleList
group by middleList.DepotName
Which return the following incorrect results:
Please help.

Okay so I found the problem.
It seems like the rows are being counted and not the actual values, thus adding this to the count insured that they were being counted properly:
count(case when middleList.NearMiss <> '0' then 0 end ) as NearMiss
End result being:

Related

SQL: If there are two rows that contain same record, want it to display one

based on my question above, below is the SQL
SELECT ets_tools.tools_id, ets_borrower.fullname, ets_team.team_name, ets_borrow.time_from,
ets_borrow.time_to, ets_borrow.borrow_id FROM ets_tools
INNER JOIN ets_tools_borrow ON ets_tools.tools_id = ets_tools_borrow.tools_id
INNER JOIN ets_borrow ON ets_borrow.borrow_id = ets_tools_borrow.borrow_id
INNER JOIN ets_borrower ON ets_borrower.badgeid = ets_borrow.badgeid
INNER JOIN ets_team ON ets_team.team_id = ets_borrower.team_id
WHERE ets_tools.borrow_id IS NOT NULL AND ets_borrow.status_id = 1 AND ets_borrow.time_to IS NULL
and the result display like this:
From the image above, we can see that the borrow_id with value 1 display two rows. Now, how to display only one borrow_id for value 1 since its duplicate the same things.
Anyone can help?
Assuming you want to retain the record having the smallest tools_id, you could aggregate by the other columns and take the MIN of tools_id:
SELECT
MIN(ets_tools.tools_id) AS tools_id,
ets_borrower.fullname,
ets_team.team_name,
ets_borrow.time_from,
ets_borrow.time_to,
ets_borrow.borrow_id
FROM ets_tools
INNER JOIN ets_tools_borrow ON ets_tools.tools_id = ets_tools_borrow.tools_id
INNER JOIN ets_borrow ON ets_borrow.borrow_id = ets_tools_borrow.borrow_id
INNER JOIN ets_borrower ON ets_borrower.badgeid = ets_borrow.badgeid
INNER JOIN ets_team ON ets_team.team_id = ets_borrower.team_id
WHERE
ets_tools.borrow_id IS NOT NULL AND
ets_borrow.status_id = 1 AND
ets_borrow.time_to IS NULL
GROUP BY
ets_borrower.fullname,
ets_team.team_name,
ets_borrow.time_from,
ets_borrow.time_to,
ets_borrow.borrow_id;
Try this:
Change the SELECT to SELECT TOP 1 WITH TIES
And at the end add ORDER BY ROW_NUMBER() OVER(PARTITION BY ets_borrow.borrow_id ORDER BY ets_tools.tools_id)

How to sum a count of bookings to display total bookings for location and total value for location

I am writing a report that needs to show the number of bookings taken for a location with the total value of those bookings.
How do I sum the bookings column and show only one row for the location, that includes the columns set out in the example of expected data?
Select Statement Below:
SELECT
Locations.Description as LocationsDesc,
Locations.LocationGUID,
Venues.VenueName,
Venues.VenueGUID,
count (Bookings.BookingID) as Bookings,
Departments.DepartmentName,
Departments.DepartmentGUID,
sum(SalesTransactionDetails.NetDetailValue) as NetDetailValue,
sum(SalesTransactionDetails.DetailValue) as DetailValue,
SUM(CASE When Salestransactionlines.itemtype = 1 Then SalesTransactionDetails.NetDetailValue Else 0 End ) as RentalFee,
SUM(CASE When Salestransactionlines.itemtype = 2 Then SalesTransactionDetails.NetDetailValue Else 0 End ) as ExtraFee,
SalesTransactions.SalesTransactionGUID
FROM BookingLinesDetails
INNER JOIN Bookings ON BookingLinesDetails.BookingGUID=Bookings.BookingGUID
INNER JOIN Locations ON BookingLinesDetails.LocationGUID=Locations.LocationGUID
INNER JOIN Venues on Venues.Venueguid = Locations.Venueguid
INNER JOIN SalesTransactionDetails ON BookingLinesDetails.BookingLinesDetailGUID=SalesTransactionDetails.BookingLinesDetailGUID
INNER JOIN SalesTransactionLines ON SalesTransactionDetails.SalesTransactionLineGUID=SalesTransactionLines.SalesTransactionLineGUID
INNER JOIN SalesTransactions ON SalesTransactionLines.SalesTransactionGUID=SalesTransactions.SalesTransactionGUID
INNER JOIN Departments on Departments.DepartmentGUID = Locations.DepartmentGUID
WHERE
BookingLinesDetails.StartDateTime >= dbo.InzDateOnly(#pFromDate) and
BookingLinesDetails.StartDateTime < DateAdd(day,1,dbo.inzDateOnly(#pToDate)) and
Departments.DepartmentGUID in (Select GUID from dbo.InzSplitGUID(#DepartmentID)) and
(#IncludeAllLocationGroupsInVenues <> 0 or (#IncludeAllLocationGroupsInVenues = 0 )) and
Venues.VenueGUID in (Select GUID from dbo.InzSplitGUID(#VenueID)) and
salesTransactions.Status = 1 and -- remove cancelled
salestransactions.receiptonly = 0
GROUP BY
Locations.Description,
Locations.LocationGUID,
Venues.VenueName,
Venues.VenueGUID,
Departments.DepartmentName,
Departments.DepartmentGUID,
SalesTransactions.SalesTransactionGUID
The output is currently:
Desired output is:
LocationsDesc LocationGUID VenueGUID Bookings DepartmentName NetDetailValue DetailValue ExtraFee
Location - Deck Room 348A43F12 7DAD77BE 33 Aquatics Centre 2059.46 2162.5 0
I have attempted several versions of Count and sum. I believe I need to make the query a derived table and then select from that, but am not sure how to go about it, even if that is the answer.
Thank you in advance.

Query from multiple tables with multiple where conditions in the tables

I'm trying to get a count of all speakers who are active regarding that item as well as the total of speakers who correlate to a certain item. The first LEFT JOIN for the total speakers works, but the other for ONLY the active speakers regarding that item doesn't, any help is appreciated. The SQLFiddle is here
http://sqlfiddle.com/#!3/b579d/1
But when I try to add in the portion where you would get the number of active speakers
(LEFT JOIN (SELECT COUNT (tbl_SpeakerCard_Log.SpeakerName)
WHERE tbl_Speaker_Log.Spoken = 0)
ON tbl_AgendaList.AID = tbl_SpeakerCard_Log.AID)
under the previous LEFT JOIN I get an error. I'm 100% sure the query is wrong in some form, but I'm not sure how to approach it.
*NOTE: Spoken/Active are interchangeable, I just use different wording to clarify what I'm looking for.
EDIT: This is the desired output
http://imgur.com/yP1FKxg
You can use conditional aggregation to do this:
SELECT
AgendaList.AID,
AgendaList.Item,
COUNT(SpeakerList.SPID) as SpeakerTotal,
SUM(CASE WHEN SpeakerList.Spoken = 0 THEN 1 ELSE 0 END) as ActiveSpeakers
FROM AgendaList
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
GROUP BY AgendaList.AID, AgendaList.Item;
Sample SQL Fiddle
Or you could use count instead of sum (which might be clearer):
COUNT(CASE WHEN Spoken = 0 THEN Spoken END) as ActiveSpeakers
SQL FIDDLE
WITH sTotal AS (
SELECT AgendaList.AID, AgendaList.Item, COUNT( SpeakerList.SPID) as SpeakerTotal
FROM AgendaList
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
GROUP BY AgendaList.AID, AgendaList.Item
),
sActive AS (
SELECT AgendaList.AID, AgendaList.Item, COUNT( SpeakerList.SPID) as SpeakerActive
FROM AgendaList
LEFT JOIN SpeakerLIST ON AgendaList.AID = SpeakerList.AID
WHERE SpeakerLIST.Spoken = 0
GROUP BY AgendaList.AID, AgendaList.Item
)
SELECT sTotal.*, sActive.SpeakerActive
FROM sTotal left join
sActive on sTotal.AID = sActive.AID

Only return value that matches the ID on table 1

I have tried all possible joins and sub-queries but I cant get the data to only return one value from table 2 that exactly matches the vendor ID. If I dont have the address included in the query, I get one hit for the vendor ID. How can I make it so that when I add the address, I only want the one vendor that I get prior to adding the address.
The vendor from table one must be VEN-CLASS IS NOT NULL.
This was my last attempt using subquery:
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENMAST.VENDOR_CONTCT,
APVENMAST.TAX_ID,
Subquery.ADDR1
FROM (TEST.dbo.APVENMAST APVENMAST
INNER JOIN
(SELECT APVENADDR.ADDR1,
APVENADDR.VENDOR_GROUP,
APVENADDR.VENDOR,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENADDR APVENADDR
INNER JOIN TEST.dbo.APVENMAST APVENMAST
ON (APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP)
AND (APVENADDR.VENDOR = APVENMAST.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)) Subquery
ON (APVENMAST.VENDOR_GROUP = Subquery.VENDOR_GROUP)
AND (APVENMAST.VENDOR = Subquery.VENDOR))
INNER JOIN TEST.dbo.APVENLOC APVENLOC
ON (APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENLOC.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)
Try this:
SELECT APVENMAST.VENDOR_GROUP
, APVENMAST.VENDOR
, APVENMAST.VENDOR_VNAME
, APVENMAST.VENDOR_CONTCT
, APVENMAST.TAX_ID
, APVENADDR.ADDR1
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN (
select VENDOR_GROUP, VENDOR, ADDR1
, row_number() over (partition by VENDOR_GROUP, VENDOR order by ADDR1) r
from TEST.dbo.APVENADDR
) APVENADDR
ON APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP
AND APVENADDR.VENDOR = APVENMAST.VENDOR
AND APVENADDR.r = 1
--do you need this table; you're not using it...
--INNER JOIN TEST.dbo.APVENLOC APVENLOC
--ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
--AND APVENMAST.VENDOR = APVENLOC.VENDOR
WHERE APVENMAST.VEN_CLASS IS NOT NULL
--if the above inner join was to filter results, you can do this instead:
and exists (
select top 1 1
from TEST.dbo.APVENLOC APVENLOC
ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
AND APVENMAST.VENDOR = APVENLOC.VENDOR
)
I found another column in the APVENLOC table that I can filter on to get the unique vendor. Turns out if the vendor address is for the main office, the vendor location is set blank.
Easier than I thought it would be!
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENADDR.ADDR1,
APVENMAST.VENDOR_SNAME,
APVENADDR.LOCATION_CODE,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN TEST.dbo.APVENADDR APVENADDR
ON (APVENMAST.VENDOR_GROUP = APVENADDR.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENADDR.VENDOR)
WHERE (APVENADDR.LOCATION_CODE = ' ')
Shaji

Logic for a specific Count

I want to fill a asp:GridView with a result of a query. My query, has to count the number of ocurrences of a specific status_id IF the column 'san_proposta.credenciada_id' is different of the value 10. If the column 'san_proposta.credenciada_id' is equals of the value 10 in anothers rows, I need count all ocurrences of a specific status_id that has the 'credenciada_id' equal 10.
I'm trying the follow code, but I don't know how to do with this specifics count.
SELECT DISTINCT San_Proposta.Imovel_Id, San_Logradouro.Descricao, San_Endereco.Logradouro, San_Imovel.Numero, San_TipoComplemento.Descricao AS Expr1,
San_Imovel.Complemento, San_Imovel.TipoDsc1, San_Transacao.TransacaoSigla, San_Credenciada.Apelido, San_Transacao.Transacao_ID, COUNT(San_Proposta.StatusProposta_Id) AS NumeroProposta
FROM San_Proposta
JOIN San_Imovel
ON San_Proposta.Imovel_Id = San_Imovel.Imovel_Id
JOIN San_Endereco
ON San_Imovel.Endereco_Id = San_Endereco.Endereco_Id
JOIN San_Logradouro
ON San_Endereco.Logradouro_Id = San_Logradouro.Logradouro_Id
JOIN San_TipoComplemento
ON San_Imovel.TipoComplemento_Id = San_TipoComplemento.TipoComplemento_Id
JOIN San_Transacao
ON San_Imovel.Transacao_ID = San_Transacao.Transacao_ID
JOIN San_Credenciada
ON San_Imovel.Credenciada_Id = San_Credenciada.Credenciada_Id
WHERE (San_Imovel.Credenciada_Id = 10 OR San_Proposta.Credenciada_Id = 10)
GROUP BY San_Proposta.Imovel_Id, San_Logradouro.Descricao, San_Endereco.Logradouro, San_Imovel.Numero,
San_TipoComplemento.Descricao, San_Imovel.Complemento, San_Imovel.TipoDsc1, San_Transacao.TransacaoSigla,
San_Credenciada.Apelido, San_Transacao.Transacao_ID, San_Proposta.StatusProposta_Id,
San_Proposta.Credenciada_Id, San_Imovel.Credenciada_Id
ORDER BY San_Proposta.Imovel_Id DESC
Based on what you're saying (if I'm interpreting you correctly) it looks like
COUNT(CASE WHEN San_Proposta.credenciada_id = 10 THEN San_Proposta.StatusProposta_Id ELSE NULL END)
would work for your count.