postgresql count distinct on differect condition - sql

I'm stuck on an exercise where I need to count the total amount of unique visits to planets, but if the planet is the moon (maan), then it should be counted twice. Also the client number should be 121
select case
when objectnaam = 'Maan' then count(objectnaam)
else count(distinct objectnaam)
end as aantal_bezoeken
from klanten inner join deelnames on klanten.klantnr = deelnames.klantnr
inner join reizen on deelnames.reisnr = reizen.reisnr
inner join bezoeken on reizen.reisnr = bezoeken.reisnr
where klanten.klantnr = 121
group by objectnaam
And it gives me this result
aantal_bezoeken
1
4
1
1
but the result should be
aantal_bezoeken
7
I just need to add all these values together but I don't know how to,
or maybe there's a better more simple solution. It should be without subqueries

Try this:
select sum(aantal_bezoeken) as aantal_bezoeken from
(select case
when objectnaam = 'Maan' then count(objectnaam)
else count(distinct objectnaam)
end as aantal_bezoeken
from klanten inner join deelnames on klanten.klantnr = deelnames.klantnr
inner join reizen on deelnames.reisnr = reizen.reisnr
inner join bezoeken on reizen.reisnr = bezoeken.reisnr
where klanten.klantnr = 121
group by objectnaam) as a

Related

How to Sum Entire Column with SQL

I'm trying to Sum an entire column in SQL. The code below sums each row, but instead I just want a total row. My guess is it has to be done with GROUP BY, but the only way the query works is if I use Share_Type or Balance, neither of which sums the column. I also tried adding the CASE statement to the Group by (by leaving off 'AS MoneyMaxBalance" but I get an error message.
SELECT
CASE
WHEN SHARE_TYPE = 57 THEN SUM(BALANCE) ELSE 0
END AS MoneyMaxBalance
FROM SHARE
INNER JOIN ACCOUNT ON SHARE.MEMBER_NBR = ACCOUNT.MEMBER_NBR AND
SHARE.SHARE_NBR = ACCOUNT.ACCOUNT_NBR
INNER JOIN PRODUCT ON ACCOUNT.PRODUCT_CODE = PRODUCT.PRODUCT_CODE
GROUP BY SHARE_TYPE
If you just want one row, don't use group by:
SELECT SUM(BALANCE) AS MoneyMaxBalance
FROM SHARE s INNER JOIN
ACCOUNT a
ON s.MEMBER_NBR = a.MEMBER_NBR AND
s.SHARE_NBR = a.ACCOUNT_NBR INNER JOIN
PRODUCT p
ON a.PRODUCT_CODE = p.PRODUCT_CODE
WHERE SHARE_TYPE = 57;
SELECT SUM(CASE WHEN SHARE_TYPE = 57 THEN BALANCE ELSE 0 END) AS MoneyMaxBalance
FROM SHARE s
INNER JOIN ACCOUNT a ON s.MEMBER_NBR = a.MEMBER_NBR AND s.SHARE_NBR = a.ACCOUNT_NBR
INNER JOIN PRODUCT p ON a.PRODUCT_CODE = p.PRODUCT_CODE
Hope this Query Works fine for your case:

SQL Subquery - Repeat Where Clause?

I know this is a 101 question, but do I need to repeat the Where clause in the main query in the sub-query below? It appears to give me the same either way, but is it even needed?
FROM account a
LEFT JOIN account pa ON a.parentaccountid = pa.accountid
JOIN customeraddress ca ON a.accountid = ca.parentid
JOIN optionsetmetadata osm ON osm.entityname = 'customeraddress'
AND osm.optionsetname = 'addresstypecode'
AND ca.addresstypecode = osm.[option]
LEFT JOIN sik_warehouse w ON a.sik_warehouseid = w.sik_warehouseid
LEFT JOIN sik_deliverymethods dm ON a.sik_deliverymethodid = dm.sik_deliverymethodsid
WHERE a.accountnumber IN ('58398',
'4350',
'5076',
'4310',
'15847')
AND Addresstypecode = 2
AND ca.jms_status = 100000000
AND ca.addressnumber > (
SELECT TOP 1 ca_sub1.addressnumber
FROM customeraddress ca_sub1
JOIN account a_sub1 ON ca_sub1.parentid = a_sub1.accountid
AND ca_sub1.addressnumber > 2
order by ca_sub1.addressnumber ASC
add inline view if you want to put multiple where condition.

How to Sum a result quantity in sql server with multiple records which several joins, does it need some subquery to do it?

I am wanting to get the SUM records of a query that I am writing
I have done simple SUM aggregates in the past, but I'm a bit rusty and wonder the best approach to getting the proper results.
Example of table with Quantity (imaps_inv)
ste_id ste_acct_id stk_id qty
1 1 001 5
1 2 001 10
1 3 001 15
So the query should NOT return 3 records, but only 1 record and so the query results SHOULD be
Site ID Stocking ID Qty
1 001 30
So you can see what I want to return
inv.qty is the Quantity field I wish to SUM , and the query I wrote up based on the tables is below.
SELECT ste.ste_id, ty.ste_ty_id, inv.qty
FROM dbo.imaps_inv inv WITH(NOLOCK)
INNER JOIN dbo.imaps_ste ste WITH(NOLOCK)
ON inv.ste_id = ste.ste_id
INNER JOIN dbo.imaps_ste_ty ty
ON ty.ste_ty_id = ste.ste_ty_id
INNER JOIN dbo.imaps_stk_acct acct WITH(NOLOCK)
ON acct.ste_id = ste.ste_id
INNER JOIN dbo.imaps_stk_acct_ty aty WITH(NOLOCK)
ON aty.stk_acct_ty_id = acct.stk_acct_ty_id
WHERE
ste.inact_ind = 0
AND LTRIM(RTRIM(aty.stk_acct_ty_nm)) = 'Good'
AND acct.rsv_ind = 0
AND acct.inact_ind = 0
PLEASE LET ME KNOW WHAT I CAN PROVIDE TO MAKE IT MORE HELPFUL ( screenshots, schema etc... )
UPDATE,
well I was only getting 19 records and this co-worker said "oh, no.. you should be getting 16,000 records...
I said ok, i'm using this ste_id (site id) and when I sent him this query
SELECT distinct ste_id from [dbo].[imaps_inv] ( 20 records)
He said, to add in stk_id (stock #)
SELECT distinct ste_id, stk_id from [dbo].[imaps_inv] (15,910 records)
Therefore I updated my query to which I finally have the proper results and figured I would update my question with the combination of the persons answer along with me tweaking the code as other person certainly does not have the schema and records etc..
Final working query
SELECT ste.ste_id as 'Site ID', inv.stk_id as 'Stocking ID', SUM(inv.qty) Qty
FROM dbo.imaps_inv inv WITH(NOLOCK)
INNER JOIN dbo.imaps_ste ste WITH(NOLOCK)
ON inv.ste_id = ste.ste_id
INNER JOIN dbo.imaps_ste_ty ty
ON ty.ste_ty_id = ste.ste_ty_id
INNER JOIN dbo.imaps_stk_acct acct WITH(NOLOCK)
ON acct.ste_id = ste.ste_id
INNER JOIN dbo.imaps_stk_acct_ty aty WITH(NOLOCK)
ON aty.stk_acct_ty_id = acct.stk_acct_ty_id
WHERE
ste.inact_ind = 0
AND LTRIM(RTRIM(aty.stk_acct_ty_nm)) = 'Good'
AND acct.rsv_ind = 0
AND acct.inact_ind = 0
GROUP BY ste.ste_id, inv.stk_id
Use SUM:
SELECT ste.ste_id,
SUM(inv.qty) Qty
FROM dbo.imaps_inv inv WITH(NOLOCK)
INNER JOIN dbo.imaps_ste ste WITH(NOLOCK)
ON inv.ste_id = ste.ste_id
INNER JOIN dbo.imaps_ste_ty ty
ON ty.ste_ty_id = ste.ste_ty_id
INNER JOIN dbo.imaps_stk_acct acct WITH(NOLOCK)
ON acct.ste_id = ste.ste_id
INNER JOIN dbo.imaps_stk_acct_ty aty WITH(NOLOCK)
ON aty.stk_acct_ty_id = acct.stk_acct_ty_id
WHERE
ste.inact_ind = 0
AND LTRIM(RTRIM(aty.stk_acct_ty_nm)) = 'Good'
AND acct.rsv_ind = 0
AND acct.inact_ind = 0
GROUP BY ste.ste_id;

How to use ISNULL in a Query within a query?

My SQL Query below is now Returning the RoomsAvailable field correctly except when theres 0 rooms taken, in which the SQL command subtracts number_of_rooms with NULL and outputs NULL to the Column. I have tried numerous ISNULL variations and found that it doesnt work; anyone know how I should be doing this?
SQL :
SELECT
Hotel_2.hotel_code,
Hotel_2.hotel_country,
Room_type_rates_2.room_type_code,
Room_type_rates_2.number_of_rooms,
Types_2.room_type,
Room_type_rates_2.rates,
Room_type_rates_2.number_of_rooms -
(SELECT
DISTINCT (SELECT
COUNT(dbo.Hotel.hotel_code) AS RoomsTake
FROM
dbo.Hotel
INNER JOIN dbo.Hotel_Reservation
ON dbo.Hotel.hotel_code = dbo.Hotel_Reservation.hotel_code
INNER JOIN dbo.Room_type_rates
ON dbo.Hotel.hotel_code = dbo.Room_type_rates.hotel_code
INNER JOIN dbo.Types
ON dbo.Hotel_Reservation.room_type_code = dbo.Types.room_type_code
AND dbo.Room_type_rates.room_type_code = dbo.Types.room_type_code
WHERE
(dbo.Room_type_rates.room_type_code = Room_type_rates_1.room_type_code)
AND (dbo.Hotel.hotel_code = Hotel_1.hotel_code)
AND (dbo.Hotel_Reservation.checkin_date >= Hotel_Reservation_1.checkin_date)
AND (dbo.Hotel_Reservation.checkout_date <= Hotel_Reservation_1.checkout_date)
) AS RoomsTaken
FROM
dbo.Hotel AS Hotel_1
INNER JOIN dbo.Hotel_Reservation AS Hotel_Reservation_1
ON Hotel_1.hotel_code = Hotel_Reservation_1.hotel_code
INNER JOIN dbo.Room_type_rates AS Room_type_rates_1
ON Hotel_1.hotel_code = Room_type_rates_1.hotel_code
INNER JOIN dbo.Types AS Types_1
ON Hotel_Reservation_1.room_type_code = Types_1.room_type_code
AND Room_type_rates_1.room_type_code = Types_1.room_type_code
WHERE
(Hotel_Reservation_1.checkin_date >= '11/19/2011')
AND (Hotel_Reservation_1.checkout_date <= '12/01/2011')
AND (Hotel_1.hotel_country = 'Adelaide')
AND (Types_1.room_type_code = Types_2.room_type_code)
) AS RoomsAvailable
FROM
dbo.Hotel AS Hotel_2
INNER JOIN dbo.Room_type_rates AS Room_type_rates_2
ON Hotel_2.hotel_code = Room_type_rates_2.hotel_code
INNER JOIN dbo.Types AS Types_2
ON Room_type_rates_2.room_type_code = Types_2.room_type_code
Current Output :
ADL20 Adelaide CPL 6 Couple Suite 514.0000 3
ADL20 Adelaide FYU 3 Family Suite 533.0000 2
ADL20 Adelaide KNG 2 King's Bedroom 556.0000 NULL
Do you mean this?:
...ISNULL(COUNT(dbo.Hotel.*),0)...
Or is the problem that you're getting NULL at all? In that case I would suspect your JOINs may have a problem.
You can wrap an ISNULL around any nested subquery or value.

SQL Outer Join on a bunch of Inner Joined results

I received some great help on joining a table to itself and am trying to take it to the next level. The SQL below is from the help but with my addition of the select line beginning with COUNT, the inner join to the Recipient table, and the Group By.
SELECT
Event.EventID AS EventID,
Event.EventDate AS EventDateUTC,
Participant2.ParticipantID AS AwayID,
Participant1.ParticipantID AS HostID,
COUNT(Recipient.ChallengeID) AS AllChallenges
FROM Event
INNER JOIN Matchup Matchup1
ON (Event.EventID = Matchup1.EventID)
INNER JOIN Matchup Matchup2
ON (Event.EventID = Matchup2.EventID)
INNER JOIN Participant Participant1
ON (Matchup1.Host = 1
AND Matchup1.ParticipantID = Participant1.ParticipantID)
INNER JOIN Participant Participant2
ON (Matchup2.Host != 1
AND Matchup2.ParticipantID = Participant2.ParticipantID)
INNER JOIN Recipient
ON (Event.EventID = Recipient.EventID)
WHERE Event.CategoryID = 1
AND Event.Resolved = 0
AND Event.Type = 1
GROUP BY Recipient.ChallengeID
ORDER BY EventDateUTC ASC
My goal is to get a count of how many rows in the Recipient table match the EventID in Event. This code works fine except that I also want to get results where there are 0 matching rows in Recipient. I want 15 rows (= the number of events) but I get 2 rows, one with a count of 1 and one with a count of 2 (which is appropriate for an inner join as there are 3 rows in the sample Recipient table, one for one EventID and two for another EventID).
I thought that either a LEFT join or an OUTER join was what I was looking for, but I know that I'm not quite getting how the tables are actually joined. A LEFT join there gives me one more row with 0, which happens to be EventID 1 (first thing in the table), but that's all. Errors advise me that I can't just change that INNER join to an OUTER. I tried some parenthesizing and some subselects and such but can't seem to make it work.
Use:
SELECT e.eventid,
e.eventdate AS EventDateUTC,
p2.participantid AS AwayID,
p1.participantid AS HostID,
COUNT(r.challengeid) AS AllChallenges
FROM EVENT e
JOIN Matchup m1 ON m1.eventid = e.eventid
AND m1.host = 1
JOIN Matchup m2 ON m2.eventid = e.eventid
AND m2.host != 1
JOIN Participant p1 ON p1.participantid = m1.participantid
JOIN Participant p2 ON p2.participantid = m2.participantid
LEFT JOIN RECIPIENT r ON r.eventid = e.eventid
WHERE e.categoryid = 1
AND e.resolved = 0
AND e.type = 1
GROUP BY e.eventid, e.eventdate, p2.participantid, p1.participantid
ORDER BY e.eventdate