postgres how to insert values with 2 selects - postgresql

I'm trying to do a query on Postgres but it's not working. I'd like to create an insert query with 2 select:
Example :
INSERT INTO table1 (id_1, id_2)
SELECT id from table_2 where code='01',
SELECT id from table_2 where code='02';
I don't find the good syntax for this.

I believe below query will works for your use case
INSERT INTO stats(totalProduct, totalCustomer, totalOrder)
VALUES(
(SELECT COUNT(*) FROM products),
(SELECT COUNT(*) FROM customers),
(SELECT COUNT(*) FROM orders)
);
you can changes query accordingly

You can add one more SELECT to achieve this
INSERT INTO table_1 (id_1, id_2)
SELECT
(SELECT id FROM table_2 WHERE code = '01') AS Id_1,
(SELECT id FROM table_2 WHERE code = '02') AS Id_2;
Or you may try with CASE expression:
INSERT INTO table1 (id_1, id_2)
SELECT MAX(CASE WHEN code = '01' THEN id ELSE 0 END) AS Id_1,
MAX(CASE WHEN code = '02' THEN id ELSE 0 END) AS Id_2
FROM table_2
Please refer to the working fiddle on db<>fiddle

Related

Calculate difference between the row counts of tables in two schemas in PostgreSQL

I have two table with same name in two different schemas (old and new dump). I would like to know the difference between the two integration.
I have two queries, that gives old and new count:
select count(*) as count_old from(
SELECT
distinct id
FROM
schema1.compound)q1
select count(*) as count_new from(
SELECT
distinct id
FROM
schema2.compound)q2
I would like have the following output.
table_name count_new count_new diff
compound 4740 4735 5
Any help is appreciated. Thanks in advance
with counts as (
select
(select count(distinct id) from schema1.compound) as count_old,
(select count(distinct id) from schema2.compound) as count_new
)
select
'compound' as table_name,
count_old,
count_new,
count_old - count_new as diff
from counts;
I think you could do something like this:
SELECT 'compound' AS table_name, count_old, count_new, (count_old - count_new) AS diff FROM (
SELECT(
(SELECT count(*) FROM (SELECT DISTINCT id FROM schema1.compound)) AS count_old,
(SELECT count(*) FROM (SELECT DISTINCT id FROM schema2.compound)) AS count_new
)
It was probably answered already, but it is a subquery/nested query.
You can directly compute the COUNT on distinct values if you use the DISTINCT keyword inside your aggregation function. Then you can join the queries extracting your two needed values, and use them inside your query to get the output table.
WITH cte AS (
SELECT new.cnt AS count_new,
old.cnt AS count_old
FROM (SELECT COUNT(DISTINCT id) AS cnt FROM schema1.compound) AS old
INNER JOIN (SELECT COUNT(DISTINCT id) AS cnt FROM schema2.compound) AS new
ON 1 = 1
)
SELECT 'compound' AS table_name,
count_new,
count_old,
count_new = count_old AS diff
FROM cte

PostgreSQL - How to count when Distinct On

How to get count of rows for each user_id
select distinct on (user_id) *
from some_table
As in such SQL:
select user_id, count(*)
from some_table
group by user_id
Try this:
SELECT DISTINCT ON (a.user_id)
a.*
FROM
(
SELECT user_id
, count(*) OVER(PARTITION BY user_id)
FROM some_table
) a
If you want to be able to use SELECT * in order to get a "sample row", depending on how large your table is you may be able to use a correlated subquery to get the count of rows for that particular user id:
select distinct on (user_id) *
, (select count (1)
from some_table st2
where st2.user_id = some_table.user_id) as user_row_count
from some_table

SQL Server : group by with corresponding row values

I need to write a T-SQL group by query for a table with multiple dates and seq columns:
DROP TABLE #temp
CREATE TABLE #temp(
id char(1),
dt DateTime,
seq int)
Insert into #temp values('A','2015-03-31 10:00:00',1)
Insert into #temp values('A','2015-08-31 10:00:00',2)
Insert into #temp values('A','2015-03-31 10:00:00',5)
Insert into #temp values('B','2015-09-01 10:00:00',1)
Insert into #temp values('B','2015-09-01 10:00:00',2)
I want the results to contains only the items A,B with their latest date and the corresponding seq number, like:
id MaxDate CorrespondentSeq
A 2015-08-31 10:00:00.000 2
B 2015-09-01 10:00:00.000 2
I am trying with (the obviously wrong!):
select id, max(dt) as MaxDate, max(seq) as CorrespondentSeq
from #temp
group by id
which returns:
id MaxDate CorrespondentSeq
A 2015-08-31 10:00:00.000 5 <-- 5 is wrong
B 2015-09-01 10:00:00.000 2
How can I achieve that?
EDIT
The dt datetime column has duplicated values (exactly same date!)
I am using SQL Server 2005
You can use a ranking subselect to get only the highest ranked entries for an id:
select id, dt, seq
from (
select id, dt, seq, rank() over (partition by id order by dt desc, seq desc) as r
from #temp
) ranked
where r=1;
SELECT ID, DT, SEQ
FROM (
SELECT ID, DT, SEQ, Row_Number()
OVER (PARTITION BY id ORDER BY dt DESC, seq DESC) AS row_number
FROM temp
) cte
WHERE row_number = 1;
Demo : http://www.sqlfiddle.com/#!3/3e3d5/5
With trial and errors maybe I have found a solution, but I'm not completely sure this is correct:
select A.id, B.dt, max(B.seq)
from (select id, max(dt) as maxDt
from #temp
group by id) as A
inner join #temp as B on A.id = B.id AND A.maxDt = B.dt
group by A.id, B.dt
Select id, dt, seq
From #temp t
where dt = (Select Max(dt) from #temp
Where id = t.Id)
If there are duplicate rows, then you also need to specify what the query processor should use to determine which of the duplicates to return. Say you want the lowest value of seq,
Then you could write:
Select id, dt, seq
From #temp t
where dt = (Select Max(dt) from #temp
Where id = t.Id)
and seq = (Select Min(Seq) from #temp
where id = t.Id
and dt = t.dt)

getting distinct rows based on two column values

I am trying to get distinct rows from a temporary table and output them to an aspx page. I am trying to use the value of one column and get the last entry made into that column.
I have been trying to use inner join and max(). However i have been unsuccessful.
Here is the code i have been trying to do it with.
Declare #TempTable table (
viewIcon nvarchar(10),
tenderType nvarchar(20),
diaryIcon int,
customerName nvarchar(100),
projectName nvarchar(100),
diaryEntry nvarchar(max),
diaryDate nvarchar(20),
pid nvarchar(20)
)
insert into #TempTable(
viewIcon,
tenderType,
diaryIcon,
customerName,
projectName,
diaryEntry ,
diaryDate ,
pid
)
select p.viewicon,
p.[Tender Type],
1 diaryicon,
c.[Customer Name],
co.[Last Project],
d.Action,
co.[Diary Date],
p.PID
From Projects2 p Inner Join
(select distinct Pno, max(convert(date,[date of next call],103)) maxdate from ProjectDiary group by Pno
) td on p.PID = td.Pno
Inner Join contacts3 co on co.[Customer Number] = p.[Customer Number]
Inner Join Customers3 c on p.[Customer Number] = c.[Customer Number]
Inner Join ProjectDiary d on td.Pno = d.Pno
Where CONVERT(Date, co.[Diary Date], 103) BETWEEN GETDATE()-120 AND GETDATE()-60
DECLARE #contactsTable TABLE
(pid nvarchar(200),
diaryDate date)
insert into #contactsTable (t.pid, t.diarydate)
select distinct pid as pid, MAX(CONVERT(DATE, diaryDate, 103)) as diaryDate from # TempTable t group by pid
DECLARE #tempContacts TABLE
(pid nvarchar(200))
insert into #tempContacts(pid)
select pid from #contactsTable
DECLARE #tempDiaryDate TABLE (diaryDate date)
insert into #tempDiaryDate(diaryDate)
select distinct MAX(CONVERT(DATE, diaryDate, 103)) from #TempTable
select t.* from #TempTable t inner join (select distinct customerName, M AX(CONVERT(DATE, diaryDate, 103)) AS diaryDate from #TempTable group by customerName) tt on t t.customerName=t.customerName
where t.pid not in
(select Pno from ProjectDiary where convert(date,[Date Of Next Call],103) > GETDATE())
and t.viewIcon <> '098'
and t.viewIcon <> '163'
and t.viewIcon <> '119'
and t.pid in (select distinct pid from #tempContacts)
and CONVERT(DATE, t.diaryDate, 103) in (select distinct CONVERT(DATE, diaryDate, 103) f rom #tempDiaryDate)
order by CONVERT(DATE, tt.diaryDate, 103)
I am trying to get all the distinct customerName's using the max date to determine which record it uses.
Use a subquery. Without going through your entire sql statement, the general idea is:
Select [Stuff]
From table t
Where date = (Select Max(Date) from table
where customer = t.customer)

postgresql where clause behavior

I made two queries that I thought should have the same result:
SELECT COUNT(*) FROM (
SELECT DISTINCT ON (id1) id1, value
FROM (
SELECT table1.id1, table2.value
FROM table1
JOIN table2 ON table1.id1=table2.id
WHERE table2.value = '1')
AS result1 ORDER BY id1)
AS result2;
SELECT COUNT(*) FROM (
SELECT DISTINCT ON (id1) id1, value
FROM (
SELECT table1.id1, table2.value
FROM table1
JOIN table2 ON table1.id1=table2.id
)
AS result1 ORDER BY id1)
AS result2
WHERE value = '1';
The only difference being that one had the WHERE clause inside SELECT DISTINCT ON, and the other outside that, but inside SELECT COUNT. But the results were not the same. I don't understand why the position of the WHERE clause should make a difference in this case. Can anyone explain? Or is there a better way to phrase this question?
here's a good way to look at this:
SELECT DISTINCT ON (id) id, value
FROM (select 1 as id, 1 as value
union
select 1 as id, 2 as value) a;
SELECT DISTINCT ON (id) id, value
FROM (select 1 as id, 1 as value
union
select 1 as id, 2 as value) a
WHERE value = 2;
The problem has to do with the unique conditions and what is visible where. It is behavior by design.