I think i need some help with this. Tried different queries million times now but nothing is working. I want it to sum t1.a and count t2.b and show the result but it is multiplying both.
I have tried left joins, right joins, without joins but i think i have not the skills to solve this!
$query ="SELECT t1.date, t1.a, t2.date, t2.b,
SUM(t1.a) AS sum1,
COUNT(t2.b) AS sum2
FROM t1
LEFT JOIN t2
ON t1.date = t2.date
GROUP BY t1.date, t2.date
";
t1:
id date a
1 2019-05-01 5
2 2019-05-01 5
3 2019-05-01 5
4 2019-05-01 1
5 2019-05-01 1
6 2019-05-02 5
7 2019-05-02 5
8 2019-05-02 5
t2:
id date b
1 2019-05-01 d
2 2019-05-01 d
3 2019-05-01 d
4 2019-05-02 d
5 2019-05-02 d
6 2019-05-02 d
7 2019-05-02 d
8 2019-05-02 d
The result is:
2019-05-01 51 15
2019-05-02 75 15
But it should be:
2019-05-01 17 3
2019-05-02 15 5
What i´m doing wrong???
Based on your expected results, you must group each table first and then join them:
SELECT
t1.date, t1.sum1, t2.sum2
FROM (
SELECT t1.date, SUM(t1.a) AS sum1
FROM t1 GROUP BY t1.date
) t1 LEFT JOIN (
SELECT t2.date, COUNT(t2.b) AS sum2
FROM t2 GROUP BY t2.date
) t2
ON t1.date = t2.date
See the demo.
Results:
| date | sum1 | sum2 |
| ---------- | ---- | ---- |
| 2019-05-01 | 17 | 3 |
| 2019-05-02 | 15 | 5 |
Related
I have created a dataset that has columns for 2 customers:
Cust_No Transaction_date amount credit_debit running_total row_num
1 5/27/2022 800 D -200 1
1 5/26/2022 300 D 600 2
1 5/22/2022 800 C 900 3
1 5/20/2022 100 C 100 4
9 5/16/2022 500 D -300 1
9 5/14/2022 300 D 200 2
9 5/6/2022 200 C 500 3
9 5/5/2022 500 D 300 4
9 5/2/2022 300 D 800 5
9 5/2/2022 500 C 1100 6
9 5/1/2022 500 C 600 7
9 5/1/2022 100 C 100 8
The result I am looking for is:
Cust_No Transaction_date amount credit_debit running_total row_num
1 5/27/2022 800 D -200 1
1 5/26/2022 300 D 600 2
1 5/22/2022 800 C 900 3
9 5/16/2022 500 D -300 1
9 5/14/2022 300 D 200 2
9 5/6/2022 200 C 500 3
9 5/5/2022 500 D 300 4
9 5/2/2022 300 D 800 5
9 5/2/2022 500 C 1100 6
I sorted the dataset based on latest transaction for each customer.
We note the latest transaction amount and search for first occurrence of same amount that was a credit (C) and exclude the rest of the rows after it.
In the example above: Customer 9 has lastest debit transaction of 500, so we look for most recent credit transaction of 500 and exclude all the rows after that for customer 9.
Progress Made so far:
calculated the running total using logic:
sum (case when credit_debit ='C' then amount else -1*amount end) over (partition by cust_no order by transaction_date desc ) as running_total
I also got the data using lead 1,2,3,4,5 but this is not efficient and I could have multiple rows before I find the first credit number with amount same as 1st row:
case when lead(amount, 1) over(partition by cust_no order by transaction_date desc) = amount then amount else null end as lead1
No sure which dbms this is for but it need a lateral join in postgres.
It searches for the most recent transaction identified when rn = 1, then it matches that amount to an earlier credit transaction of the same amount and using the rn of that row to form a boundary of row numbers to be returned:
with CTE as (
select
Cust_No, Transaction_date, amount, credit_debit, running_total
, row_number() over(partition by cust_no order by transaction_date DESC) as rn
from mytable
)
, RANGE as (
select *
from CTE
left join lateral (
select c.rn as ignore_after
from CTE as c
where CTE.Cust_No = c.Cust_No
and CTE.amount = c.amount
and c.credit_debit = 'C'
and CTE.rn = 1
order by c.rn ASC
limit 1
) oa on true
where CTE.rn = 1
)
select
CTE.*
from CTE
inner join RANGE on CTE.rn between RANGE.rn and RANGE.ignore_after
and CTE.cust_no = RANGE.cust_no
Cust_No | Transaction_date | amount | credit_debit | running_total | rn
------: | :--------------- | -----: | :----------- | ------------: | -:
1 | 2022-05-27 | 800 | D | -200 | 1
1 | 2022-05-26 | 300 | D | 600 | 2
1 | 2022-05-22 | 800 | C | 900 | 3
9 | 2022-05-16 | 500 | D | -300 | 1
9 | 2022-05-14 | 300 | D | 200 | 2
9 | 2022-05-06 | 200 | C | 500 | 3
9 | 2022-05-05 | 500 | D | 300 | 4
9 | 2022-05-02 | 300 | D | 800 | 5
9 | 2022-05-02 | 500 | C | 1100 | 6
for postgres see: db<>fiddle here
nb: for an "outer apply" example I have also used SQL Server in the following fiddle see: db<>fiddle here
I have a dataset as in this example :
id | product_id | date | weight
1 | 454 |2019-06-26 16:08:45| 900
2 | 454 |2019-06-27 13:24:16| 900
3 | 454 |2019-06-28 10:53:42| 899
4 | 352 |2018-04-18 10:53:42| 124
5 | 352 |2018-04-19 15:26:51| 124
6 | 112 |2019-12-08 11:44:01| 065
7 | 375 |2020-03-15 08:23:43| 483
8 | 375 |2020-03-15 18:07:33| 496
9 | 375 |2020-03-16 14:32:24| 496
And I would like to get only the rows that have a weight different from the previous one or different from the next one. In the case of the example the expected output is :
id | product_id | date | weight
2 | 454 |2019-06-27 13:24:16| 900
3 | 454 |2019-06-28 10:53:42| 899
7 | 375 |2020-03-15 08:23:43| 483
8 | 375 |2020-03-15 18:07:33| 496
However, I have only reading permissions on this database, so the LAG() function does not work. What other options do I have?
Thank you!
One method uses correlated subqueries:
select t.*
from (select t.*,
(select t2.weight
from t t2
where t2.product_id = t.product_id and t2.date < t.date
order by t2.date desc
limit 1
) as prev_weight,
(select t2.weight
from t t2
where t2.product_id = t.product_id and t2.date > t.date
order by t2.date asc
limit 1
) as next_weight
from t
) t
where prev_weight <> weight or next_weight <> weight;
You can try :
SELECT DISTINCT *
FROM table t1
WHERE EXISTS (
SELECT *
FROM table t2
WHERE t1.weight <> t2.weight
AND t1.product_id = t2.product_id
)
I need to proces records one by one comparing each to its prior then move to next and do the same until last record.
Structure to proces
id dat qty dif
1 2019-05-01 2 NULL
2 2019-05-01 6 NULL
3 2019-05-01 3 NULL
1 2019-05-02 4 NULL
2 2019-05-02 7 NULL
3 2019-05-02 5 NULL
Expected result
id dat qty dif
1 2019-05-01 2 0
1 2019-05-02 4 2
2 2019-05-01 6 0
2 2019-05-02 7 1
3 2019-05-01 3 0
3 2019-05-02 5 2
For id =1 and dat= '2019-05-01' dif = (2 - 0) which is current qty minus prior qty
For id =1 and dat= '2019-05-02' dif = (4 - 2)
Do I need scrollable cursor ? How to get it ?
Since SQL Server 2008 does not support LAG, we can try simulating it using a correlated subquery:
SELECT
id,
dat,
qty,
qty - COALESCE((SELECT TOP 1 t2.qty FROM yourTable t2
WHERE t2.id = t1.id AND t2.dat < t1.dat
ORDER BY t2.dat DESC), t1.qty) AS dif
FROM yourTable t1
ORDER BY
id, dat;
Demo
id | amount
1 | 96
2 | 0.63
3 | 351.03
4 | 736
5 | 53
6 | 39
7 | 105
8 | 91
I want to get the row where sum(amount) reach 1000
please note only the row that trigger 1000
This query should do what (I think) you want:
select id, (select sum(amount)
from table1 t1
where t1.id <= table1.id) as total
from table1
having total >= 1000
limit 1
For your sample table, it gives
id total
4 1183.66
I have two following tables
table 1)
ID | HOTEL ID | NAME
1 100 xyz
2 101 pqr
3 102 abc
table 2)
ID | BOOKING ID | DEPARTURE DATE | AMOUNT
1 1 2013-04-12 100
2 1 2013-04-14 120
3 1 2013-04-9 90
4 2 2013-04-14 100
5 2 2013-04-18 150
6 3 2013-04-12 100
I want to get reault in mysql such that it take the row from table two with MAX DEPARTURE DATE.
ID | BOOKING ID | DEPARTURE DATE | AMOUNT
2 1 2013-04-14 120
5 2 2013-04-18 150
6 3 2013-04-12 100
SELECT b.ID,
b.BookingID,
a.Name,
b.departureDate,
b.Amount
FROM Table1 a
INNER JOIN Table2 b
ON a.ID = b.BookingID
INNER JOIN
(
SELECT BookingID, MAX(DepartureDate) Max_Date
FROM Table2
GROUP BY BookingID
) c ON b.BookingID = c.BookingID AND
b.DepartureDate = c.Max_date
SQLFiddle Demo
Well,
SELECT * FROM `table2` ORDER BY `DEPARTURE_DATE` DESC LIMIT 0,1
should help