Count Two Tables on shared date in Postgresql - sql

I have two separate customer tables A and B. I am trying to count the customers created in A and B in the same query by date. I can get the right data with Union All but not properly grouped.
I want the data like so:
date,count A created, count B created
4/15/2015,1,5
Instead of:
date, count
4/15/2015, 1
4/15/2015, 5
Appreciate the help!

Just use a cte, just have to be carefull if you dont have date in every day. In that case you would need a date table to get 0 when no sales.
Also try not use reserved words like date as fieldnames
with countA as (
SELECT date, count(*) as CountA
from tableA
group by date
),
countB as (
SELECT date, count(*) as CountB
from tableB
group by date
)
SELECT A.date, A.CountA, B.CountB
FROM CountA A
INNER JOIN CountB B
ON A.date = B.date
With a table AllDates to solve day without sales
SELECT T.date,
CASE
WHEN A.CountA IS NULL THEN 0
ELSE A.CountA
END as CountA,
CASE
WHEN B.CountB IS NULL THEN 0
ELSE B.CountB
END as CountB
FROM AllDates T
LEFT JOIN CountA A
ON T.date = A.date
LEFT JOIN CountB B
ON T.date = B.date

select a.dte
,a.count a_created
,b.count b_created
from
(select dte,count(*)from table_a group by dte) a
,(select dte,count(*)from table_b group by dte) b
where b.dte=a.dte
SQLFIDDLE DEMO
OR
You can use achieve this by using PostgreSQL's tablefunc
start bty creating CREATE EXTENSION if not exists tablefunc;
and following as an example
create table table_a (dte date,is_created int);
create table table_b (dte date,is_created int);
insert into table_a values('2015-10-07',1);
insert into table_a values('2015-10-07',1);
insert into table_a values('2015-10-07',1);
insert into table_a values('2015-10-07',1);
insert into table_a values('2015-10-07',1);
insert into table_b values('2015-10-07',2);
by using crosstab() the select should be
SELECT *
FROM crosstab(
'select dte,''a_created'' col,count(*) created from table_a group by dte
union all
select dte, ''b_created'' col,count(*) created from table_b group by dte')
AS ct("date" DATE, "a_created" BIGINT, "b_created" BIGINT);

Related

SQL - summarize results from multiple tables

I have the following simple SQL query that I need to run on 3 tables:
SELECT
A.date,
SUM(A.number)
FROM A
GROUP BY
A.date
But I have two other tables (B and C) on which I'd like to run the same query. And combine the results into one table as output.
I am expecting the output to look something like:
date
A.number
B.number
C.number
2022
12322.1
9999999
888888
We can try the following union approach:
SELECT
date,
SUM(CASE WHEN src = 'A' THEN number ELSE 0 END) AS A_sum,
SUM(CASE WHEN src = 'B' THEN number ELSE 0 END) AS B_sum,
SUM(CASE WHEN src = 'C' THEN number ELSE 0 END) AS C_sum
FROM
(
SELECT date, number, 'A' AS src FROM A
UNION ALL
SELECT date, number, 'B' FROM B
UNION ALL
SELECT date, number, 'C' FROM C
) t
GROUP BY date
ORDER BY date;
Here is my approach:
Create Table TableA
(
Dates Date,
Number Int
)
GO
Create Table TableB
(
Dates Date,
Number Int
)
GO
Create Table TableC
(
Dates Date,
Number Int
)
GO
Insert Into TableA
Values ('2023-01-01', 100000),
('2023-01-02',30000)
GO
Insert Into TableB
Values ('2023-01-01', 200000),
('2023-01-02',10000)
GO
Insert Into TableC
Values ('2023-01-01', 400000),
('2023-01-02',20000)
GO
SELECT * from
(
Select *,'A' Det from TableA
UNION ALL
Select *,'B' from TableB
UNION ALL
Select *,'C' from TableC
)ABC
PIVOT
(SUM(ABC.Number) FOR Det IN (A,B,C))
XYZ
DROP TABLE TableA
DROP Table TableB
DROP table TableC
IMO best option is to create calendar first and then left join created calendar with different tables:
Calendar is important to gather data from join.
And i'ts quite odd if you have column date as year.
In my oppinion it's to small level of complexity.
But ok. Let's say that you have only year.
Create table with years.
Create Table Years
(
years int
)
next:
INSERT INTO Years(years )
VALUES
(2022),(2021),(2020),(2019),(2018),(2017),(2016),(2015)
eg.
SELECT
y.*,
sum(a.number) as SumA,
sum(b.number) as SumB,
sum(c.number) as SumC
FROM Years as y
left join
table_a a
on
y.years=a.date
left join
table_b b
on
y.years=b.date
left join
table_c c
on
y.years=c.date
GROUP BY
y.years
Hopefully this helps!
Please let me know if it works as you wanted.

What is the bigquery sql inner join equivalent for rows?

I have the following 2 tables:
I would like to create a table where
all rows of table 1 are included
if the timestamp of any row of table 2 falls in between the timestamp and endTime of any row of table 1, then include the row.
The resultant table would like:
There are columns/fields that are common to both tables, but I haven't included them for brevity. Basically, I am looking for the equivalent of an inner join operation but then instead of adding the rows of table 2 as columns, add them as rows. I have written a sample code whilst experimenting with inner join as below:
WITH table_a AS (
SELECT 'x' AS event, 1 AS timestamp, 5 AS endtime, 'a' AS field1
UNION ALL SELECT 'x', 100, 200, 'b'
),
table_b AS (
SELECT 'y' AS event, 2 AS timestamp, 'm' AS field2
UNION ALL SELECT 'y', 25, 'n'
UNION ALL SELECT 'y', 150, 'o'
)
SELECT
table_a.*,
table_b.*
FROM table_a JOIN table_b
Any thoughts what bigquery sql functions I can use?
Use below
select *, null field2 from table_a union all
select distinct b.event, b.timestamp, null, cast(null as string), field2
from table_b b
join table_a a
on b.timestamp between a.timestamp and a.endtime
if applied to sample data in your question - output is

PostgreSQL query to list all values of a column that are common between tables

I have a column named endate(its values are dates) present in five tables, straddle0, straddle1, straddle2, straddle3 and straddle4. My assumption regarding the data is that, one table's endate values are not present in any of the other mentioned tables(can be repeated in the same table though). But to confirm, I want to list all the endate values that might be present in multiple tables (like 01-01-2017 is present in straddle0 and also in straddle4 or 02-02-2017 is present in straddle1 and also in straddle3 and straddle5).
What is the PostgreSQL query for the same?
I would use UNION ALL and a GROUP BY/HAVING:
Schema (PostgreSQL v13)
CREATE TABLE t1 (
enddate date
);
CREATE TABLE t2 (
enddate date
);
CREATE TABLE t3 (
enddate date
);
INSERT INTO t1
VALUES (CURRENT_DATE), (CURRENT_DATE+1);
INSERT INTO t2
VALUES (CURRENT_DATE), (CURRENT_DATE+2), (CURRENT_DATE+2);
INSERT INTO t3
VALUES (CURRENT_DATE+2), (CURRENT_DATE+3);
Query #1
WITH all_dates AS (
SELECT 't1' AS table_name, enddate
FROM t1
UNION ALL
SELECT 't2' AS table_name, enddate
FROM t2
UNION ALL
SELECT 't3' AS table_name, enddate
FROM t3
)
SELECT enddate, ARRAY_AGG(DISTINCT table_name) AS appears_in
FROM all_dates
GROUP BY 1
HAVING COUNT(DISTINCT table_name) > 1
ORDER BY 1;
enddate
appears_in
2022-05-07T00:00:00.000Z
t1,t2
2022-05-09T00:00:00.000Z
t2,t3
View on DB Fiddle
Not sure what format you want the result in. I made two scripts - a simple one and a more detailed one. Perhaps this is what you need
Here is dbfiddle
with data(dt, t) as (
select distinct endate, 0 from straddle0 union all
select distinct endate, 1 from straddle1 union all
select distinct endate, 2 from straddle2 union all
select distinct endate, 3 from straddle3 union all
select distinct endate, 4 from straddle4
)
select dt, min(t) as t from data group by dt having count(*) = 1;

how to SUM two columns in different table between two date

this my query but result false where number row different , that's to say whenever tableA select 2 row and tableB select 3 result is false
select sum(tableA.value)+sum(tableB.value1) )
from tableA,tableB
where tableA.data between '2016-01-21' and '2016-03-09'
and tableB.date2 between '2016-01-21' and '2016-03-09'
You need to do the sums in subqueries before joining. A simple rule: never use commas in the from clause.
select coalesce(avalue, 0) + coalesce(bvalue, 0)
from (select sum(a.value) as avalue
from tableA a
where a.data between '2016-01-21' and '2016-03-09'
) a cross join
(select sum(b.value) as bvalue
from tableB b
where b.data between '2016-01-21' and '2016-03-09'
) b;
OK . So here's what my understanding is.
You are trying to sum up two columns from two different tables and get the sum of the summed up columns. isn't ?? Correct me if I am wrong.If this is the case then
A Simple Subquery Can Come To Your Rescue.
Select
(Select SUM(value) From tableA
where data between '2016-01-21' and '2016-03-09') +
(Select SUM(value1) From tableB
where date2 between '2016-01-21' and '2016-03-09') FinalValue

How to get Original Rows filtered by a HAVING Condition?

What is the method in T-SQL to select the orginal values limited by a HAVING attribute. For example, if I have
A|B
10|1
11|2
10|3
How would I get all the values of B (Not An Average or some other summary stat), Grouped by A, having a Count (Occurrences of A) greater than or equal two 2?
Actually, you have several options to choose from
1. You could make a subquery out of your original having statement and join it back to your table
SELECT *
FROM YourTable yt
INNER JOIN (
SELECT A
FROM YourTable
GROUP BY
A
HAVING COUNT(*) >= 2
) cnt ON cnt.A = yt.A
2. another equivalent solution would be to use a WITH clause
;WITH cnt AS (
SELECT A
FROM YourTable
GROUP BY
A
HAVING COUNT(*) >= 2
)
SELECT *
FROM YourTable yt
INNER JOIN cnt ON cnt.A = yt.A
3. or you could use an IN statement
SELECT *
FROM YourTable yt
WHERE A IN (SELECT A FROM YourTable GROUP BY A HAVING COUNT(*) >= 2)
A self join will work:
select B
from table
join(
select A
from table
group by 1
having count(1)>1
)s
using(A);
You can use window function (no joins, only one table scan):
select * from (
select *, cnt=count(*) over(partiton by A) from table
) as a
where cnt >= 2