Is there is way to get SUM() of column without GROUPING by joining multiple tables in SQL Server - sql

I am getting SUM() of amount in CrowdfundedUser table by GROUP BY CrowdfundID but difficult to get SUM() because all columns are unique.
Crowdfund:
CrowdfundID
GoalAmount
StartedDate
9
10000
09/02/2022
5
20000
10/02/2022
55
350000
11/02/2022
444
541256
12/02/2022
54
78458
13/02/2022
CrowdfundedUser:
ID
User ID
CrowdfundID
Amount
744
12214
9
1000
745
4124
5
8422
746
12214
55
784
747
12214
444
874
748
64554
54
652
CrowdfundiPaymentTransaction:
CrowdfundedUserID
Invoice
Amount
PaymentDate
744
RA45A14124
1000
09/02/2022
745
RA45A12412
8422
10/02/2022
746
RA45U14789
784
11/02/2022
747
RA45F12457
874
12/02/2022
748
RA45M00124
652
13/02/2022
My query :
SELECT
c.CrowdfundID,
SUM(cu.Amount),
SUM(cpt..Amount)
FROM
Crowdfund c
INNER JOIN
CrowdfundedUser cu ON c.CrowdfundID = cu.CrowdfundID
INNER JOIN
CrowdfundiPaymentTransaction cpt ON cu.ID = cpt.CrowdfundedUserID
GROUP BY
c.CrowdfundID

SELECT c.CrowdfundID,
SUM(cu.Amount) OVER (
ORDER BY c.CrowdfundID) Amount,
SUM(cpt..Amount) OVER (
ORDER BY c.CrowdfundID) CptAmount
FROM Crowdfund c
INNER JOIN CrowdfundedUser cu ON c.CrowdfundID = cu.CrowdfundID
INNER JOIN CrowdfundiPaymentTransaction cpt ON cu.ID = cpt.CrowdfundedUserID

Related

SQL-Group by ID´s from tables

So i have 2 tables let's say
Orders(order_id,etc...) and
order_items(order_id,...)
I want to get an overview of how many orders have x amount of items by grouping the id from orders with the x amount of ids from order items
So lets say atm I have this scenario:
orders:
order_id
???
???
11
1
Pending
33
3
Pending
44
3
Pending
22
2
Pending
444
4
Pending
order_items:
order_id
???
???
???
???
11
7
32
132
469,99
22
5
192
124
519,99
22
7
27
92
800,74
33
11
6
128
849,99
33
10
95
106
109,99
33
5
271
148
549,59
44
9
284
138
54,99
44
8
174
117
798,26
44
6
131
34
279,99
44
11
271
58
549,59
444
9
284
138
54,99
444
8
174
117
798,26
444
6
131
34
279,99
444
11
271
58
549,59
With this query:
SELECT count(o.order_id) as ORDER_count,
(SELECT count(*)
FROM order_items ol
WHERE o.order_id = ol.order_id) AS ORDER_ITEMS_count
FROM orders o, order_items ol
WHERE o.order_id = ol.order_id
GROUP BY o.order_id,ol.order_id;
I'm getting:
ORDER_COUNT
ORDER_ITEMS_COUNT
4
4
1
1
2
2
3
3
4
4
and i'm expecting something like:
ORDER_COUNT
ORDER_ITEMS_COUNT
5
5
1
1
2
2
3
3
Can you please point out what am I missing?
Thankx for the help
I want to get an overview of how many orders have x amount of items by grouping the id from orders with the x amount of ids from order items
First select all orders and count their items. Then use this result to count how many orders share a number of items.
SELECT number_of_items, COUNT(*) AS how_many_orders
FROM
(
SELECT o.order_id, COUNT(oi.order_id) as number_of_items
FROM orders o
LEFT OUTER JOIN order_items ON oi.order_id = o.order_id
GROUP BY o.order_id
) orders_with_item_counts
GROUP BY number_of_items
ORDER BY number_of_items;
If every order has at least one item (which seems likely), you can change the LEFT OUTER JOIN to an INNER JOIN.

Using multiple and interdepended CROSS-APPLY across multiple tables

How can I use either CROSS APPLY (or INNER JOIN) to get data from one table based on the values in other tables?
I.e. I have the following tables:
Table Descriptions:
ProdID
Description
TrackNum
361
Test 1
499
388
Test 2
003
004
5599
238
Test 3
499
361
Test 10
555
004
Test 40
555
Table Products:
ProdID
ProductName
Price
361
P1
5.00
388
P2
5.00
004
P3
12.00
238
P4
6.00
515
P5
7.00
636
P6
7.00
775
P7
7.00
858
P8
8.00
Table Invoices:
ProdID
TrackNum
InvoiceID
361
499
718
388
199
718
004
499
718
238
499
718
361
555
333
004
555
444
361
111
444
388
222
333
616
116
565
717
116
565
361
003
221
388
003
221
004
5599
728
What I need my query to do is to:
Go into Invoices table first, and get only records that matches specified InvoiceID and TrackNum;
Then go into Products table and get only rows that have matches on ProdID between the data I pulled out in Step #1 and the data existis in the Products table.
Then finally get all columns from the Descriptions table, but only for the rows which I got in the Step #2 and which matches on ProdID.
What I need to have at the end is something like this (if I get more columns that is fine, but I do not want to get more rows):
ProdID
Description
TrackNum
361
Test 1
499
004
5599
238
Test 3
499
I have following query (and I have tried using INNER JOIN and CROSS APPLY) - but it returns me more rows than I need:
SELECT * FROM [Descriptions] AS [DES]
CROSS APPLY
(
select * from [Invoices] AS [INV] where [INV].[TrackNum] = '499' AND [INV].[InvoiceID] = '718'
) [INV]
CROSS APPLY
(
select * from [Products] AS [GP]
WHERE [GP].[ProdID] = [INV].[ProdID]
) [GP2]
WHERE
[DES].[ProdID] = [GP2].[ProdID]
order by [DES].[ProdID] asc
SELECT
*
FROM
invoices AS i
LEFT JOIN
descriptions AS d
ON d.prodid = i.prodid
AND d.tracknum = i.tracknum -- you don't have this, but I think it's required.
LEFT JOIN
products AS p
ON p.prodid = i.prodid
WHERE
i.invoiceid = 718
AND i.tracknum = 499
ORDER BY
i.prodid
One thing that concerns me is that both the invoices and descriptions have a column named tracknum, but your query and expected data indicate that you don't want to include that in the join? That's very confusing and either a poor column name, or a mistake in your query and example results.
Based on what you describe you want the following, start with your Invoices table and a where clause to get the right rows, then join on Products and Descriptions.
I'm also guessing that you want to match the Description on TrackNum? Since it appears you have a unique Description per ProdId/TrackNum combination.
select [INV].[ProdID], [DES].[Description], [INV].[TrackNum]
from [Invoices] as [INV]
inner join [Products] as [GP] on [GP].[ProdID] = [INV].[ProdID]
inner join [Descriptions] on [DES].[ProdID] = [GP].[ProdID] and [DES].[TrackNum] = [INV].[TrackNum]
where [INV].[TrackNum] = '499' AND [INV].[InvoiceID] = '718'
order by [DES].[ProdID] asc;
Note: You normally only use a 'CROSS APPLY' for queries where you want to run/evaluate something per row in your main table.
In this case the Inner Join is sufficient. You don't need to use Cross Apply

Get nearest date column value from another table in SQL Server

I have two tables A and B,
Table A
PstngDate WorkingDayOutput
12/1/2020 221
12/3/2020 327
12/4/2020 509
12/5/2020 418
12/7/2020 390
12/8/2020 431
12/9/2020 244
12/10/2020 246
12/11/2020 314
12/12/2020 301
12/14/2020 411
12/15/2020 530
12/16/2020 554
12/17/2020 300
12/18/2020 375
12/23/2020 402
12/24/2020 302
12/25/2020 269
12/26/2020 382
12/28/2020 608
Table B
PstngDate HolidayOutput isWorkingDay
12/2/2020 20 0
12/6/2020 24 0
12/13/2020 31 0
12/19/2020 82 0
12/22/2020 507 0
12/27/2020 537 0
Expected output:
PstngDate WorkingDayOutput HolidayOutput
12/1/2020 221 20
12/3/2020 327
12/4/2020 509
12/5/2020 418 24
12/7/2020 390
12/8/2020 431
12/9/2020 244
12/10/2020 246
12/11/2020 314
12/12/2020 301 31
12/14/2020 411
12/15/2020 530
12/16/2020 554
12/17/2020 300
12/18/2020 375 589
12/23/2020 402
12/24/2020 302
12/25/2020 269
12/26/2020 382 537
12/28/2020 608
I want to join TableB to TableA with nearest lesser date column. If you see Expectedoutput table, day 18 row of holidayoutput column is taking sum of day19 and day22 of table B.
I want to join TableB to TableA with nearest lesser date column
This sounds like a lateral join:
select a.*, coalesce(b.holidayquantity, 0) as holidayquantity
from a
outer apply (
select top (1) b.*
from b
where b.pstng_date >= a.pstng_date
order by b.pstng_date
) b
You can use self left join as follows:
Select pstng_date, workingDayQuantity,
HolidayQuantity,
workingDayQuantity + HolidayQuantity as total
From
(Select a.*, b.HolidayQuantity,
Row_number() over (partirion by a.psrng_date order by b.pstng_date) ad rn
From tablea a join tableb b On b.pstng_date > a.pstng_date) t
Where rn=1

FULL JOIN doesn't work in two ways

I'm trying to write a FULL JOIN statement in SQL but it doesn't work as fine as I would like.
Here is my full statement
SELECT
t.tacNom, bh.heuresChiffrees,
SUM(ISNULL(heures,0)) + SUM(ISNULL(minutes,0)/60) as HeuresRealisee, (ISNULL(bh.heuresChiffrees,0) - (SUM(ISNULL(heures,0)) + (SUM(ISNULL(minutes,0))/60))) as Solde,
(SUM(DISTINCT minutes)%60) as Soldeminutes
FROM tbl_BalanceHeures bh
FULL OUTER JOIN tbl_HeuresTimbrage_new ht ON ht.idProjet = bh.proIdProjetExterne
AND ht.idxTache = bh.idxTache
AND ht.idxDep= bh.idxDepartement
INNER JOIN tbl_Taches t on t.idTache = bh.idxTache
WHERE proIdProjetExterne = '00Z 000104' AND bh.idxDepartement = 184
GROUP BY t.tacNom ,bh.heuresChiffrees
Here are the result of the statement
idTache heuresChiffrees HeuresRealisee Solde
332 25 0 25
330 50 0 50
327 100 42 58
331 100 23 77
Here are the records in my table tbl_Balance and the statement
select t.idTache, bh.heuresChiffrees
from tbl_BalanceHeures bh
INNER JOIN tbl_Taches t on t.idTache = bh.idxTache
WHERE proIdProjetExterne= '00Z 000104' AND bh.idxDepartement = 184
idTache heuresChiffrees
330 50
331 100
327 100
332 25
Here are the records in tbl_HeuresTimbrage and the statement
Select t.idTache, ht.heures as heuresRealisees
From tbl_HeuresTimbrage_new ht
INNER JOIN tbl_Taches t on t.idTache = ht.idxTache
WHERE idProjet= '00Z 000104' AND ht.idxDep = 184
idTache heuresRealisees
327 32
331 23
327 10
334 4
So, In my FULL JOIN Statement I am expected to find
IdTache heuresChiffrees Heures Realisees
327 100 10
330 50 NULL (or 0)
331 100 23
332 25 NULL (or 0)
334 NULL(or 0) 4
I've tried to put my WHERE clause in the Full JOIN but it doesn't work
It's most likely because of your WHERE clause. It is acting on the joined result, and so if the A side is null, it will eliminate those rows.
You can change it to be a condition of the join instead, as so:
FROM A
FULL OUTER JOIN B
ON B.idProjet = A.proIdProjetExterne
AND B.idxTache = A.idxTache
AND B.idxDep= A.idxDepartement
AND A.proIdProjetExterne = 'xxx'
AND A.idxDepartement = 184
However, without seeing your actual data or schema, this is a bit of a guess...

SQL Server 2000 query

I have a created a few tables containing multiple records from several users so I can simulate circumstances.
I created the following query:
SELECT
a.celid, a.callid, a.active, a.messagetext,
b.jactive, a.cel_time, c.username, a.muserid
FROM level2 a, calls b , login c
WHERE a.callid = b.jid
AND a.muserid = c.loginid
AND b.jid = 92
AND a.win = 0
AND b.userid = 12
ORDER BY
cel_time ASC
and got the following as result
545 92 2 hello1 2 2011-09-18 16:32:17.000 phil01 21
546 92 1 hello2 2 2011-09-18 16:42:38.000 phil01 21
547 92 2 hello3 2 2011-09-18 16:59:08.000 danny 16
548 92 1 hello4 2 2011-09-18 20:46:21.000 phil01 21
549 92 1 hello5 2 2011-09-18 20:47:16.000 phil01 21
550 92 1 hello6 2 2011-09-19 19:32:15.000 phil01 21
551 92 1 hello7 2 2011-09-19 19:34:14.000 phil01 21
but I actually want this result to be distinct on muserid and return only return two rows.
I have studied distinct value description but can not seem to get this accomplished.
How would I accomplish this?
Use this SQL:
SELECT
a.celid, a.callid, a.active, a.messagetext,
b.jactive, a.cel_time, c.username, a.muserid
FROM level2 a
JOIN calls b ON a.callid = b.jid
JOIN login c ON a.muserid = c.loginid
JOIN
(SELECT l2.muserid, MAX(l2.cel_time) as max_time
FROM level2 l2
GROUP BY l2.muserid) d ON (d.muserid = a.muserid AND a.cel_time = d.max_time)
WHERE b.jid = 92
AND a.win = 0
AND b.userid = 12