Table:1
Date Customer Amount
12-Dec ABC 200
15-Dec ABC 300
Output:
I need to group the data by Customer and need to take the latest date for that unique record.
Date Customer Amount
15-Dec ABC 500
You seems to want aggregation :
select max(to_date(date, 'DD-MON-YYYY')), cust, sum(amount)
from table t
group by cust;
Related
I have a snapshot table like the following
id
name
value
date
123
ABC Corp
500
yesterday
123
ABC Corp
500
today
456
XYZ Ltd.
700
today
123
ABC Corp
500
tomorrow
456
XYZ Ltd.
700
tomorrow
789
PQR Consulting
100
tomorrow
I would like to get the new rows only like the following table from the above snapshot table using sql
id
name
value
date
456
XYZ Ltd.
700
today
789
PQR Consulting
100
tomorrow
I need a pointer whether to follow the window function (like LAG() etc.) to get the new table. or more simple solution is there? Thanks in advance!
There are a few options here, one of them is to use a cte or a derived table to add row_number based on the date column to the table, and the other is to use first_value window function. I'm pretty sure the derived table solution would be better in terms of performance, but I don't have the time to test.
Here's what I would do:
;WITH cte AS
(
SELECT id, name, value, date, ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) as rn
FROM snapshotTable
)
SELECT id, name, value, date
FROM cte
WHERE rn = 1;
To get the earliest records all you need to do is remove the DESC from the order by clause.
I have a table that stores, number of fruits sold on each day. Stores number of items sold on particular date.
CREATE TABLE data
(
code VARCHAR2(50) NOT NULL,
amount NUMBER(5) NOT NULL,
DATE VARCHAR2(50) NOT NULL,
);
Sample data
code |amount| date
------+------+------------
aple | 1 | 01/01/2010
aple | 2 | 02/02/2010
orange| 3 | 03/03/2010
orange| 4 | 04/04/2010
I need to write a query, to list out, how many apple and orange sold for jan and february?
--total apple for jan
select sum(amount) from mg.drum d where date >='01/01/2010' and cdate < '01/02/2020' and code = 'aple';
--total apple for feb
select sum(amount) from mg.drum d where date >='01/02/2010' and cdate < '01/03/2020' and code = 'aple';
--total orange for jan
select sum(amount) from mg.drum d where date >='01/01/2010' and cdate < '01/02/2020' and code = 'orange';
--total orange for feb
select sum(amount) from mg.drum d where date >='01/02/2010' and cdate < '01/03/2020' and code = 'orange';
If I need to calculate for more months, more fruits, its tedious.is there a short query to write?
Can I combine at least for the months into 1 query? So 1 query to get total for each month for 1 fruit?
You can use conditional aggregation such as
SELECT TO_CHAR("date",'MM/YYYY') AS "Month/Year",
SUM( CASE WHEN code = 'apple' THEN amount END ) AS apple_sold,
SUM( CASE WHEN code = 'orange' THEN amount END ) AS orange_sold
FROM data
WHERE "date" BETWEEN date'2020-01-01' AND date'2020-02-29'
GROUP BY TO_CHAR("date",'MM/YYYY')
where date is a reserved keyword, cannot be a column name unless quoted.
Demo
select sum(amount), //date.month
from mg.drum
group by //date.month
//data.month Here you can give experssion which will return month number or name.
If you are dealing with months, then you should include the year as well. I would recommend:
SELECT TRUNC(date, 'MON') as yyyymm, code,
SUM(amount)
FROM t
GROUP BY TRUNC(date, 'MON'), code;
You can add a WHERE clause if you want only some dates or codes.
This will return a separate row for each row that has data. That is pretty close to the results from your four queries -- but this does not return 0 values.
select to_char(date_col,'MONTH') as month, code, sum(amount)
from mg.drum
group by to_char(date_col,'MONTH'), code
How to choose customers who have made a large amount of payments in December 2018 if we take into account the exchange rate
I have a table:
Trandate date - transaction date
Transum numeric (20,2) - amount of payment
CurrencyRate numeric (20,2) - currency exchange rate
ID_Client Trandate Transum CurrencyRate Currency
--------------------------------------------------------
1 2018.12.01 100 1 UAH
1 2018.12.02 150 2 USD
2 2018.12.01 200 1 UAH
3 2018.12.01 250 3 EUR
3 2018.12.02 300 1 UAH
3 2018.12.03 350 2 USD
7 2019.01.08 600 1 UAH
but I think that "max" is not at all what I need
SELECT ID_Client, MAX(Transum*CurrencyRate)
FROM `Payment.TotalPayments`
WHERE YEAR(Trandate) = 2018
AND MONTH(Trandate) = 12
I need something this
ID_Client Transum
3 1750
Where 1750 is a "UAH" and 350USD + 300UAH + 250EUR, exchange rate of USD is 2, exchange rate of EUR is 3.
If you're trying to get the sum of transaction amounts by client for the year 2018 and month of December, you could write it like this:
SELECT ID_Client, SUM(Transum*CurrencyRate) as payment_total_converted
FROM `Payment.TotalPayments`
WHERE YEAR(Trandate) = 2018
and MONTH(Trandate) = 12
group by ID_Client
If you want things grouped by each client, year, and month in a given date range, you'd write it like this:
SELECT ID_Client, YEAR(Trandate) as tran_year, MONTH(Trandate) as tran_month,
SUM(Transum*CurrencyRate) as payment_total_converted
FROM `Payment.TotalPayments`
WHERE Trandate between '2018-12-01' and '2019-01-01'
group by ID_Client, YEAR(Trandate), MONTH(Trandate)
I added a column name for your computed column so that the result set is still relational (columns need distinct names).
I'd recommend reading up on the SQL 'group by' clause (https://www.w3schools.com/sql/sql_groupby.asp) and aggregate (https://www.w3schools.com/sql/sql_count_avg_sum.asp, https://www.w3schools.com/sql/sql_min_max.asp) operators.
I think you want sum(). Then you can order by the result:
SELECT ID_Client, SUM(Transum*CurrencyRate) as total
FROM `Payment.TotalPayments`
WHERE Trandate >= '2018-12-01' AND Transdate < '2019-01-01'
GROUP BY ID_Client
ORDER BY total DESC;
customer price date
123 100 1-Jan-15
321 200 2-Jan-15
123 10 3-Jan-15
123 50 4-Jan-15
321 150 5-Jan-15
123 100 6-Jan-15
123 300 7-Jan-15
321 500 8-Jan-15
123 700 9-Jan-15
I would like to take see SUM(Price) between dates 3-Jan and 7-Jan group by customer
Something like:
select customer,sum(price) from table group by customer
having date between 3-Jan-2015 and 8-Jan-2015
This prompts me to have date either in the select or group by clause. When I include it, it groups by Date also.
Desired output is:
123 460
The HAVING clause filters results after the grouping and aggregation, so in order to do this any fields you want in the HAVING clause must be in the GROUP BY or SELECT lists. The WHERE clause filters the rows before doing the grouping and aggregation.
To get the results you want, simply move the date between... condition into a WHERE clause:
SELECT customer,SUM(price)
FROM table
WHERE date BETWEEN 3-Jan-2015 AND 8-Jan-2015
GROUP BY customer
I have one table with following data..
saleId amount date
-------------------------
1 2000 10/10/2012
2 3000 12/10/2012
3 2000 11/12/2012
2 3000 12/10/2012
1 4000 11/10/2012
4 6000 10/10/2012
From my table I want result with max of sum amount between dates 10/10/2012 and 12/10/2012 which for the data above will be:
saleId amount
---------------
1 6000
2 6000
4 6000
Here 6000 is the max of the sums (by saleId) so I want ids 1, 2 and 4.
You have to use Sub-queries like this:
SELECT saleId , SUM(amount) AS Amount
FROM Table1
GROUP BY saleId
HAVING SUM(amount) =
(
SELECT MAX(AMOUNT) FROM
(
SELECT SUM(amount) AS AMOUNT FROM Table1
WHERE date BETWEEN '10/10/2012' AND '12/10/2012'
GROUP BY saleId
) AS A
)
See this SQLFiddle
This query goes through the table only once and is fairly optimised.
select top(1) with ties saleid, amount
from (
select saleid, sum(amount) amount
from tbl
where date between '20121010' and '20121210'
group by saleid
) x
order by amount desc;
You can produce the SUM with the WHERE clause as a derived table, then SELECT TOP(1) in the query using WITH TIES to show all the ones with the same (MAX) amount.
When presenting dates to SQL Server, try to always use the format YYYYMMDD for robustness.