Summing together values from the same table in different databases - sql

I have a table on each database for a region of a company with the number of sales per month like so:
Region1.dbo.SalesPerMonth Region2.dbo.SalesPerMonth
ID Month Sales ID Month Sales
1 Jan 23 1 Jan 21
2 Feb 19 2 Feb 15
3 Jan 31 3 Jan 25
... ... ... ... ... ...
I am looking to write a query to join these tables into one table that shows the sales for the entire company per month, so it has the total sales from all regions added together:
AllRegions
ID Month Sales
1 Jan 44
2 Feb 34
3 Jan 56
... ... ...
I am however new to SQL and am not sure how to go about doing so. Any help or advice on how to write the query would be greatly appreciated.

Union together the two tables, and then aggregate by ID and Month to generate the sum of sales.
SELECT
ID, Month, SUM(Sales) AS Sales
FROM
(
SELECT ID, Month, Sales
FROM Region1.dbo.SalesPerMonth
UNION ALL
SELECT ID, Month, Sales
FROM Region2.dbo.SalesPerMonth
) t
GROUP BY
ID, Month
ORDER BY
ID;
Demo here:
Rextester

Try this:
WITH DataSource AS
(
SELECT *
FROM Region1.dbo.SalesPerMonth
UNION ALL
SELECT *
FROM Region2.dbo.SalesPerMonth
)
SELECT [id]
,[Month]
,SUM(Sales) AS Sales
FROM DataSource
GROUP BY [id]
,[Month]

Related

SQL Bigquery Counting repeated customers from transaction table

I have a transaction table that looks something like this.
userid
orderDate
amount
111
2021-11-01
20
112
2021-09-07
17
111
2021-11-21
17
I want to count how many distinct customers (userid) that bought from our store this month also bought from our store in the previous month. For example, in February 2020, we had 20 customers and out of these 20 customers 7 of them also bought from our store in the previous month, January 2020. I want to do this for all the previous months so ending up with something like.
year
month
repeated customers
2020
01
11
2020
02
7
2020
03
9
I have written this but this only works for only the current month. How would I iterate or rewrite it to get the table as shown above.
WITH CURRENT_PERIOD AS (
SELECT DISTINCT userid
FROM table1
WHERE DATE(orderDate) BETWEEN DATE_TRUNC(CURRENT_DATE(),MONTH) AND DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
),
PREVIOUS_PERIOD AS (
SELECT DISTINCT userid
FROM table1
WHERE DATE(orderDate) BETWEEN DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH),MONTH) AND LAST_DAY(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH))
)
SELECT count(1)
FROM CURRENT_PERIOD RC
WHERE RC.userid IN (SELECT DISTINCT userid FROM PREVIOUS_PERIOD)
You can summarize to get one record per month, use lag(), and then aggregate:
select yyyymm,
countif(prev_yyyymm = date_add(yyyymm, interval -1 month)
from (select userid, date_trunc(order_date, month) as yyyymm,
lag(date_trunc(order_date, month)) over (partition by userid order by date_trunc(order_date, month)) as prev_yyyymm
from table1
group by 1, 2
) t
group by yyyymm
order by yyyymm;

Convert columns data into rows in PostgreSQL

I have data in the following format.
order_no rate jan feb mar ....
1 1200 2 4
2 1000 1 5
3 2400 14 3
Now I want to transpose this table to get the following output.
order_no rate month unit
1 1200 feb 2
1 1200 mar 4
2 1000 jan 1
2 2400 mar 5 and so on..
How can I do this?
You can create a "temporary" normalized view on the data using a cross join:
select o.order_no, o.rate, v.*
from orders o
cross join lateral (
values
('jan', jan),
('feb', feb),
('mar', mar),
...
('dec', dec)
) as v(month, unit)
If you want to exclude the months with no values, you can add
where v.unit is not null
to the query
Online example: http://rextester.com/PBP46544
One simple approach uses UNION:
SELECT order_no, rate, 'jan' AS month, jan AS unit UNION ALL
SELECT order_no, rate, 'feb', feb UNION ALL
...
SELECT order_no, rate, 'dec', dec
ORDER BY order_no;
Postgres also has CROSSTAB capabilities. But to use that, you have to be really good at SQL, which I'm not.
Try this
Select order_no, rate, 'jan' as month, jan as unit
from tbl
where jan is not null
union all
Select order_no, rate, 'feb' as month, feb as unit
from tbl
where feb is not null
union all
Select order_no, rate, 'mar' as month, mar as unit
from tbl
where mar is not null
order by order_no

SQL Group By weeks and months in the same time (Redshift)

In the code below I am selecting 42 days period and grouping it by SNAPSHOT_WEEK (where SNAPSHOT_WEEK has a number from 1 to 52(53) during the year).
SELECT
CASE
WHEN video_code = 'A' THEN 'Seller'
WHEN video_code = 'B' THEN 'Vendor'
WHEN video_code = 'C' THEN 'Others'
END AS CATEGORY
TO_CHAR(snapshot_time - DATE_PART('dow', snapshot_time)::int + 4, 'IW') AS SNAPSHOT_WEEK,
SUM(VIOLATION_COUNT)
FROM my_table
WHERE 1=1
AND snapshot_time BETWEEN '20180505'::date - '41 days'::interval AND '20180505'::date -- to calculate WoW
GROUP BY
CATEGORY, SNAPSHOT_WEEK;
Output for this query looks like this:
CATEGORY WEEK OR MONTH SUM_VIOLATION_COUNT
A 14 954
B 14 454
C 14 299
A 15 954
B 16 454
Is it possible, in the same query, beside grouping by week, group this data by month where month should start from 28th of one month to 28th of second month?
For example, in my output I need column that will show following values:
CATEGORY WEEK OR MONTH SUM_VIOLATION_COUNT
A 14 954
B 14 454
C 14 299
A 15 954
B 16 454
C 17 299
A 28 March 9354
B 28 March 2454
C 28 March 5354
A 28 April 1354
...... ..... .....
Where "28 March" - means number of violation between 28-Feb and 28 March; "28 April" - number of violation between 28 Feb and 28 April etc.
Is that possible to do using the same query?
You can do that with WITH Subquery, this will allow you do to run the query once on the database and group by twice based on your logic.
Your query has some disconnects between your column names but again it will look like something like this
P.S. Union requires number of columns should be same in both selects
WITH ALLDATA AS (
SELECT
CASE
WHEN video_code = 'A' THEN 'Seller'
WHEN video_code = 'B' THEN 'Vendor'
WHEN video_code = 'C' THEN 'Others'
END AS CATEGORY
TO_CHAR(snapshot_time - DATE_PART('dow', snapshot_time)::int + 4, 'IW') AS SNAPSHOT_WEEK,
SUM(VIOLATION_COUNT) SUM_VIOLATION_COUNT
FROM my_table
WHERE 1=1
AND snapshot_time BETWEEN '20180505'::date - '41 days'::interval AND '20180505'::date -- to calculate WoW
GROUP BY
CATEGORY, SNAPSHOT_WEEK)
SELECT CATEGORY, SNAPSHOT_WEEK, SUM_VIOLATION_COUNT FROM ALLDATA
UNION
SELECT CATEGORY, SNAPSHOT_WEEK, SUM_VIOLATION_COUNT FROM ALLDATA
GROUP BY <your month grouping logic>
To reiterate the logic in pseudo code
WITH ALLDATA AS (
SELECT <your base data without group by> )
SELECT columns FROM ALLDATA
GROUP BY <weekly group by logic>
UNION
SELECT columns FROM ALLDATA
GROUP BY <monthly group by logic>
You would need to UNION the output of two separate queries to generate those results.
The basic rule is that one input row will map to (at most) one output row.

in sql how to arrange rows of data into colum using Pivot

Here i have a simple table i want to display all rows respected that year display in single column
Year Month Amt
1999 Jan 520
1999 Feb 100
199 Mar 200
2000 Jan 500
2000 Feb 200
I want to display these table as
Year Jan Feb Mar
1999 520 100 200
2000 500 200 null
I had Written query as invoice its my table name
select
[Jan] as January,
[Feb] as Feburary,
[March] as Feburary,
from(
select Year,month,amount from invoice)x
PIVOT(
sum(amount)
for month in([jan],[Feb],[March])
)p
Please Try This Query
create table #Invoice
(
ID int identity(1,1),
Year varchar(4),
Month varchar(3),
Amount int
)
insert into #Invoice (Year, Month, Amount) values ('1999','Jan',520),('1999','Feb',100),('1999','Mar',200),
('2000','Jan',500),('2000','Feb',200)
select Year, [Jan], [Feb],[Mar],[Grand Total]
from (
select Year, Month, Amount
from #Invoice
Union all
select Year, 'Grand Total', SUM(Amount)
from #Invoice
group by year
)dd
pivot (
sum(Amount) for Month in ([Jan], [Feb],[Mar],[Grand Total])
) piv
drop table #Invoice
You can achieve it using CTE. You can't GROUP BY YEAR within the PIVOT table operator, the PIVOT operator infers the grouped columns automatically. This seems to work
WITH Pivoted
AS
(
SELECT *
FROM table1
PIVOT
(
sum([Amt]) FOR [month] IN ( [jan],[Feb],[Mar])
) AS p
)
SELECT
Year,
sum([Jan]) as January,
sum([Feb]) as Feburary,
sum([Mar]) as March
FROM Pivoted
GROUP BY Year;
REXTESTER DEMO

Grouping data on SQL Server

I have this table in SQL Server:
Year Month Quantity
----------------------------
2015 January 10
2015 February 20
2015 March 30
2014 November 40
2014 August 50
How can I identify the different years and months adding two more columns that group the same years with a number and then different months in sequential way like the example
Year Month Quantity Group Subgroup
------------------------------------------------
2015 January 10 1 1
2015 February 20 1 2
2015 March 30 1 3
2014 November 40 2 1
2014 August 50 2 2
You can use DENSE_RANK to calculate the groups for you:
SELECT t1.*, DENSE_RANK() OVER (ORDER BY Year DESC) AS [Group],
DENSE_RANK() OVER (PARTITION BY Year ORDER BY DATEPART(month, Month + ' 01 2010')) AS [SubGroup]
FROM t1
ORDER BY 4, 5
See this fiddle.
To associate group and subgroup with a number you can do this:
WITH RankedTable AS (
SELECT year, month, quantity,
ROW_NUMBER() OVER (partition by year order by Month) AS rn
FROM yourtable)
SELECT year, month, quantity,
SUM (CASE WHEN rn = 1 THEN 1 ELSE 0 END) OVER (ORDER BY YEAR) as year_group,
rn AS subgroup
FROM RankedTable
Here ROW_NUMBER() OVER clause calculates rank of a month within a year.
And SUM() ... OVER calculates running SUM for the months with rank 1.
SQL Fiddle