Postgresql Union to combine two table - postgresql

I Have two similar table but new & old.
table01 Old
id
customer
product
quantity
001
Cust001
Soap
200
002
Cust002
Shampoo
23
003
Cust003
Ketchup
30
table01 New
id
customer
product
quantity
002
Cust002
Shampoo
70
003
Cust003
Ketchup
50
what i want to get on union is id 001 from old table, and id 002 - 003 from new table
id
customer
product
quantity
001
Cust001
Soap
200
002
Cust002
Shampoo
70
003
Cust003
Ketchup
50
After i try with union all or simple union it's not show like what i want.
How to get the view like my wanted table use case or what should i do after union?
*now, my real table got hundres transaction id

demo
PostgreSQL DISTINCT ON with different ORDER BY
WITH cte AS (
(
SELECT
*
FROM
customer1
ORDER BY
quantity)
UNION ALL (
SELECT
*
FROM
customer2
ORDER BY
quantity))
SELECT DISTINCT ON (id, customer, product)
*
FROM
cte
ORDER BY
1,
2,
3,
4 DESC;
UNION ALL make all the rows from tables is there, then distinct on remove duplicates, using ORDER BY to decide which row is being "saved" in an DISTINCT ON operation.

Related

Count users with more than X amount of transactions within Y days by date

Scenario: Trying to count more active users for time series analysis.
Need: With postgreSQL(redshift) Count customers that have more than X unique transactions within Y days from said date, group by date.
How do i achieve this?
Table: orders
date
user_id
product_id
transaction_id
2022-01-01
001
003
001
2022-01-02
002
001
002
2022-03-01
003
001
003
2022-03-01
003
002
003
...
...
...
...
Outcome:
date
active_customers
2022-01-01
10
2022-01-02
12
2022-01-03
9
2022-01-04
13
You may be able to use the window functions LEAD() and LAG() here but this solution may also work for you.
WITH data AS
(
SELECT o.date
, o.user_id
, COUNT(o.trans_id) tcount
FROM orders o
WHERE o.date BETWEEN o.date - '30 DAYS'::INTERVAL AND o.date -- Y days from given date
GROUP BY o.date, o.user_id
), user_transaction_count AS
(
SELECT d.date
, COUNT(d.user_id) FILTER (WHERE d.tcount > 1) -- X number of transactions
OVER (PARTITION BY d.user_id) user_count
FROM data d
)
SELECT u.date
, SUM(u.user_count) active_customers
FROM user_transaction_count u
GROUP BY u.date
ORDER BY u.date
;
Here is a DBFiddle that demos a couple options.

Need to combine the sales of 2 records with different ID's and the record with highest sale id should be in the result set

I have a table with records belonging to same person but the person was assigned with 2 different id's.
I need to combine the sales and then hold on to the id having highest sales.
For Example:
ID Name Sales
1 ABC 10
4 ABC 60
5 xyz 100
6 xyz 10
I need result as
ID Name Sales
4 ABC 70
5 XYZ 110
Please help me with a sql query for the above.
try this:
create table #mytable
(id int,
name nvarchar(20),
Sales int)
insert into #mytable
values
(1,'ABC',10),
(4,'ABC',60),
(5,'xyz',100),
(6,'xyz',10)
select (select top(1) ID
from #mytable r2
where r2.name=r1.name
and r2.Sales=MAX(r1.Sales))as ID,
name,
sum(Sales)
from #mytable r1
group by name
drop table #mytable

Display MAX and 2nd MAX SALARY from the EMPLOYEE table

SELECT max(salary),
(SELECT MAX(SALARY) FROM EMPLOYEE
WHERE SALARY NOT IN(SELECT MAX(SALARY) FROM EMPLOYEE)) as 2ND_MAX_SALARY;
This is giving me the error: FROM keyword not found where expected
You want the top 2 of your table ordered by one of the columns (the FETCH NEXT clause is available from Oracle 12c R1)
SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 2
FETCH NEXT 2 ROWS ONLY;
Use
SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 2
FETCH NEXT 2 ROWS WITH TIES;
if you want to return all employees that have the 1st or 2nd highest salary: There might only be one highest salary amount in the company, but more than one employee who gets that amount. Those rows are the ties.
If you're on Oracle database version lower than 12c, rank analytic function might help.
For sample rows:
SQL> select * from employee order by salary desc;
ENAME SALARY
---------- ----------
KING 5000 --> highest salary
FORD 3000 --> Ford and Scott "share" the 2nd
SCOTT 3000 --> highest salary
JONES 2975
BLAKE 2850
CLARK 2450
ALLEN 1600
TURNER 1500
MILLER 1300
WARD 1250
MARTIN 1250
ADAMS 1100
JAMES 950
SMITH 800
14 rows selected.
In a subquery (or a CTE, as I did), calculate rank for each salary and then, in the main query, select rows that rank as to top salaries:
SQL> with temp as
2 (select ename,
3 salary,
4 rank() over (order by salary desc) rnk
5 from employee
6 )
7 select ename, salary
8 from temp
9 where rnk <= 2
10 order by rnk desc;
ENAME SALARY
---------- ----------
SCOTT 3000
FORD 3000
KING 5000
SQL>
SELECT MAX(salary) AS max_salary,
(SELECT MAX(salary)
FROM employee
WHERE salary NOT IN (SELECT MAX(salary)
FROM employee
)
) AS 2nD_max_salary
FROM employee;

Writing a select query

I have two tables:
table1 =tbl_main:
item_id fastec_qty
001 102
002 200
003 300
004 400
table2= tbl_dOrder
order_id item_id amount
1001 001 30
1001 002 40
1002 001 50
1002 003 70
How can I write a query so that the result of the tables are as follows:
item_id amount difference
001 102 22
002 200 160
003 300 230
004 400 400
The difference between the amount in table 1 and the total amounts disbursed from the Table 2.
SELECT q.item_id, a.fastec_qty AS amount, a.fastec_qty - q.amount AS difference
FROM (
SELECT item_id, SUM(amount) AS amount
FROM tbl_dOrder
GROUP BY item_id
) q
JOIN tbl_main a ON a.item_id = q.item_id
Here this query is going to first SUM the amounts from tbl2 grouped by the item_id, then it's going to JOIN the results of that query with the first table so it can do the calculation for the difference column.

Select a row when data is missing

i got a question.
I use this straight foreward query to retrieve data on a daily basis. part of the data is an ID.
For example, i got ID's 001 002 003 and 004. Every ID has some columns with data.
I daily generate a report based on that data.
A typical day looks lke
ID Date Value
001 2013-07-02 900
002 2013-07-02 800
003 2013-07-02 750
004 2013-07-02 950
Select *
FROM
myTable
WHERE datum > now() - INTERVAL '2 days' and ht not in (select ht from blocked_ht)
order by ht, id;
Some times the import for 1 id fails. So my data looks like
ID Date Value
001 2013-07-02 900
003 2013-07-02 750
004 2013-07-02 950
Its vital to know that 1 ID is missing, visualized in my report (made in Japserreports)
So i instert an ID without a date and value 0 and eddited the query:
SELECT *
FROM
"lptv_import" lptv_import
WHERE datum > now() - INTERVAL '2 days' and ht not in (select ht from negeren_ht) OR datum IS NULL
order by ht, id;
Now the data looks like this:
001 2013-07-02 900
002 800
003 2013-07-02 750
004 2013-07-02 950
How can i select from the tabel the row without the date WHEN ID 002 WITH a date is missing?
Hmm, this looks more compliacted than i thought...
select
id, coalesce(datum::text, 'NULL') as "date", "value"
from
(
select distinct id
from lptv
) id
left join
lptv using (id)
where
datum > now() - INTERVAL '2 days'
and not exists (select ht from negeren_ht where ht = lptv.ht)
order by id