PostgreSQL - Table union using loop without using UNION keyword - postgresql

(New to PostgreSQL)
I have the below table as source table
Column A Column B Column C Column D Column E Column F
AS QW ZX ER CV GH
AD QE ZC ET CB GJ
AF QR ZV EY CN GK
AG QT ZB EU CM GL
I need to get the resultant table/view as below:
Column A Column B Column C Column D Name Value
AS QW ZX ER Column E CV
AS QW ZX ER Column F GH
AD QE ZC ET Column E CB
AD QE ZC ET Column F GJ
AF QR ZV EY Column E CN
AF QR ZV EY Column F GK
AG QT ZB EU Column E CM
AG QT ZB EU Column F GL
I have used the below query to get the resultant table:
select
"Column A",
"Column B",
"Column C",
"Column D",
'Column E' as "Name",
"Column E" as "Value"
from tablexyz
UNION
select
"Column A",
"Column B",
"Column C",
"Column D",
'Column F' as "Name",
"Column F" as "Value"
from tablexyz
As if you can see the script, I have used UNION and attached the two subsets (hardcoded the values in the Name column). But, in the future, I would be getting Column G, Column H and so on... Hence I would like to run a loop such that it will calculate how many columns are available other than Column A, Column B, Column C, Column D and those many iterations should happen in the loop along with data UNIONed with Column names as Names column and column values as Values in the Resultant table.
I have also checked the loop statements available in the other websites but I am getting the "Notice" keyword for each iteration and also select statements are not working inside the Loop. It would be great if you could provide me the script to get the resultant table.

Related

Agreggating multiple category columns in postgreSQL

I have this table in my postgreSQL db that I need to aggregate in categories.
The table called "table1" looks like this
Column A
Column B
Column C
Apple
Volks
200
Apple
Volks
350
Lime
BMW
200
Apple
BMW
200
Lime
BMW
400
I want the output to look like this:
Column A
Column B
Column C
Apple
Volks
550
Apple
BMW
200
Lime
BMW
600
I've tried using groupby and sum(Column C) but it didn't worked out.
SELECT distinct Column A, Column B, sum(Column C) as "Sum of C"
GROUP BY Column A, Column B, Column C
FROM public.table1
You should not be aggregating and grouping the same column, and distinct is irrelevant given a group by already results in distinct groups; your syntax is also wrong, that query would result in an error as From must precede Group By.
However you can use distinct in an aggregation, like so:
SELECT Column_A, Column_B, sum(distinct Column_C) as "Sum of C"
FROM public.table1
GROUP BY Column_A, Column_B;

Need t-sql view with difficult sort order

I have a sorting issue in a sql-server 2017 view. To simplify the question: I have a table with hierarchical data and has two columns: key and txt. The key column is used for the hierarchical order and has one, two or three positions. The txt column just has random text values. I need to sort the data, but on a combination of both key and txt columns. To be more precise, I need to get from the left view (sorted on key column) to the right view (the sort I need):
key
txt
key
txt
A
de
A
de
A1
al
A1
al
A2
nl
A3
gt
A3
gt
A31
oj
A31
oj
A2
nl
B
pf
B
pf
B1
zf
B4
ar
B2
br
B42
cd
B3
qa
B41
ik
B31
lb
B2
br
B32
bn
B3
qa
B33
kt
B32
bn
B4
ar
B33
kt
B41
ik
B31
lb
B42
cd
B1
zf
So the view should first show the top level (key is one character) and then below that row the txt values alphabetically (key is two characters). But if the key has three characters, the rows must be placed alphabetically under the matching key with two characters. In the example above, row with key A31 must be listed directly under the row with key A3, row with key B42 must be directly below B4 and B41 below B42, etc.
I have tried many things, but I cannot get the rows with the three character keys to appear directly under the proper two character key rows.
This is an example of what I tried:
SELECT *
FROM tbl
ORDER BY CASE LEN(key) WHEN 1 THEN key
WHEN 2 THEN LEFT(key, 1) + '10'
ELSE LEFT(key, 1) + '20'
END, txt
But this places the rows with three character keys at the bottom of the list...
Hope someone can put me in the right direction.
This is a really complicated process because your rules are more complicated than your schema. Here's my attempt, using window functions to group things together and determine which 2-character substring has the lowest txt value, then perform a series of ordering conditionals:
WITH cte AS
(
SELECT [key],
l = LEN([key]),
k1 = LEFT([key],1),
k2 = LEFT([key],2),
txt
FROM dbo.YourTableName
),
cte2 AS
(
SELECT *,
LowestTxt = MIN(CASE WHEN l = 2 THEN txt END) OVER (PARTITION BY k2),
Len2RN = ROW_NUMBER() OVER (PARTITION BY k2
ORDER BY CASE WHEN l = 2 THEN txt ELSE 'zzzzz' END)
FROM cte
)
SELECT [key], txt
FROM cte2
ORDER BY k1,
CASE WHEN l > 1 THEN 1 END,
LowestTxt,
CASE WHEN l = 2 THEN 'aaa' ELSE txt END,
Len2RN;
Example in this working fiddle.

JPA equivalent of PostgreSQL with null comparison

I have a requirement something like there are two db tables A and B.
Table A and table B both have column 'merit' of type integer. The requirement is to find the entries from table A those have merit that matches with the least merit number in table B.
If merit in B is NULL for all the entries, the query should result all the entries from table A.
If merit in B has valid numbers, the query should result the entries of A those match the least merit number in table B.
Sample data is like this::
TABLE A TABLE B
COL1 COL2 MERIT COL1 COL2 MERIT
a ab 1 c ac 1
b bc 2 d ad 3
From above data the least merit in B is 1 so, only the matching entry should result from Table A.
If merit column in B is null for all the entries ie. B has no valid number for merit, two entries from A should result.
So, I came up with the below sql query::
select A.* from A where A.merit IS NOT DISTINCT FROM (
select min(B.merit) from B where B.merit IS NOT NULL);
I am unable to write the JPA equivalent of this sql because of "IS NOT DISTINCT FROM".
The below queries are not working.
select a from A a where a.merit in (select min(b.merit) from B b where b.merit is not null)
select a from A a where a.merit = (select min(b.merit) from B b where b.merit is not null)
My environment is POSTGRESQL, HIBERNATE in QUARKUS.
Thanks for any suggestions.

Postgres delete query - Syntax error near count(*)

I want to delete records from F table which has only one H record and that record has thrown 76 errorkode.
I am getting syntax error as i am joining and doing the count(*) check . Is there any correct way to do it???
delete from F fb where id in(select h.id from H h
join MI m on h.m_i_id=m.id
join ERROR e on e.m_i_id=m.id
join ERRORKODE ek on e.errorkode_id=ek.id where errorkode=76) and
select count(*) from H h where h.f_id = fb.id) =1
The where clause of delete has two conditions separated by and, the second one is query which should be in parenthesis. There is missing left parenthesis (before select keyword).

Add a new column dynamically in resultset

I have a query as below;
Existing Query - select A,B,C from table1.
Table2 has columns X,Y
The new query should have a new column(D) in the result-set. the value of D will be calculated based on column X.
D's calculation should be D = (C * X), Here to decide the row of column X from table2 -Y can be used in where condition. Y & A are not same but similar
I did not understand what did you mean by "Y & A are not same but similar". I assume Y and A can be used as joining keys. If so, the anwer would be:
SELECT T1.A,T1.B,T1.C,T1.C*T2.X AS D
FROM Table1 T1
JOIN Table2 T2 ON T1.A=T2.Y
I hope this helps!