power bi get new table filed from linked table - postgresql

i have 3 linked table:
tableA whith iddocument, total, date
tableB whith iddetail, iddocument, qta, price
tableC whitn idstorychange, iddetail,user_id, typechange, old_value,new_value, date_change
the tables are linked in powerbi:
tableA join tableB (1-N, tableB.iddocument ->tableB.iddocument)
tableB join tableC (1-N, tableB.iddetail->tableC.iddetail)
in need a new table whith fields:
tableA.iddocument,max(tableC.datechange)
where new_value is in some value and group by tableA.iddocument
in T-sql would be:
select
tableA.iddocument,max(tableC.date_change)
from tableA
inner join tableB on tableB.iddocument = tableA.iddocument
inner join tableC on tableC.iddetail = tableB.iddetail
where
tableC.typechange = 'type1' and tableC.new_value in (5,8) and tableC.user_id in (82,87,90,91)
group by tableA.iddocument
i can't create a view in db, i can only read table, i need solve in powerbi.
the table in power bi is imported (not direct query)
thx a lot

Related

Hibernate - more than one row returned by a subquery used as an expression

I have a scenario to extract information from three(Table1, Table2, Table4) tables based on the common id of Table1
For extracting information from Table 4, I have to look another intermediate table(Table3) for the common Id between Table 3 and Table 4. The query result of Table 4 information would contain more than a single row as query response.
I have written the following HQL(Hibernate Query) for my requirement
select t1,t2,(select t4.column1 from Table4 t4
join Table3 t3 on t4.column0=t3.column0 and t3.column1=t1 and t3.column2='desired_value') from Table1 t1
join Table2 t2 on t2.column1=t1.column1
where t1.column0=:id and t1.column3=:value
I have entity classes for all the four tables.
How can I select the multiple rows from the subquery
What is the euiquvalent of POSTGRESQL array_agg() / string_agg() method in Spring Data JPA?
Without the subquery, I am able to fetch Object[] response with my Entity class objects.
How can I add my subquery in order to retrieve all my desired data in a Single transaction without creating a separate query method in my Repository class?
What I tried so far:
select t1,t2,(select new List(t4.column1) from Table4 t4
join Table3 t3 on t4.column0=t3.column0 and t3.column1=t1 and t3.column2='desired_value') from Table1 t1
join Table2 t2 on t2.column1=t1.column1
where t1.column0=:id and t1.column3=:value
Below is the output object that I am trying to achieve:
List<Object[]> as my query response
where each Object[] will be of size 3 with following
Object[0] -> Table1_Entity object
Object[1] -> Table2_Entity object
Object[2] -> will be a String[] containing a specific column values from Table4 Entity class
i.e response = [[obj1, obj2, ["value1, value2","value3"]], [obj3, obj4, ["value1, value2","value3"]], ......]
Try this:
select t1,t2, (select cast(function('string_agg', t4.column1, ', ') as string) from Table4 t4
join Table3 t3 on t4.column0=t3.column0 and t3.column1=t1 and t3.column2='desired_value') from Table1 t1
join Table2 t2 on t2.column1=t1.column1
where t1.column0=:id and t1.column3=:value

If transaction_id is not null join on transaction_id else join on user id - in same join?

I would like to do a single left join from table a onto table b on transaction_id
select a.*, b.*
from tablea a
left join tableb b on b.transaction_id = a.transaction_id
However, there are cases where transaction id on either table is missing, in which case I would like to fall back onto joining on a.user_id = b.user_id. If user_id is also missing then fine, I still want to keep all records from a.
Is there a way I can tell postgres to try joining on one field and if it's missing on either table to then try joining on another field?
Is there a way to do this?
Add a 2nd join to tableb with the condition that the 1st join did not match:
select a.*,
coalesce(b1.col1, b2.col1), coalesce(b1.col2, b2.col2), .....
from tablea a
left join tableb b1 on b1.transaction_id = a.transaction_id
left join tableb b2 on b2.user_id = a.user_id and b1.transaction_id is null

How to find in a many to many relation all the identical values in a column and join the table with other three tables?

I have a many to many relation with three columns, (owner_id,property_id,ownership_perc) and for this table applies (many owners have many properties).
So I would like to find all the owner_id who has many properties (property_id) and connect them with other three tables (Table 1,3,4) in order to get further information for the requested result.
All the tables that I'm using are
Table 1: owner (id_owner,name)
Table 2: owner_property (owner_id,property_id,ownership_perc)
Table 3: property(id_property,building_id)
Table 4: building(id_building,address,region)
So, when I'm trying it like this, the query runs but it returns empty.
SELECT address,region,name
FROM owner_property
JOIN property ON owner_property.property_id = property.id_property
JOIN owner ON owner.id_owner = owner_property.owner_id
JOIN building ON property.building_id=building.id_building
GROUP BY owner_id,address,region,name
HAVING count(owner_id) > 1
ORDER BY owner_id;
Only when I'm trying the code below, it returns the owner_id who has many properties (see image below) but without joining it with the other three tables:
SELECT a.*
FROM owner_property a
JOIN (SELECT owner_id, COUNT(owner_id)
FROM owner_property
GROUP BY owner_id
HAVING COUNT(owner_id)>1) b
ON a.owner_id = b.owner_id
ORDER BY a.owner_id,property_id ASC;
So, is there any suggestion on what I'm doing wrong when I'm joining the tables? Thank you!
This query:
SELECT owner_id
FROM owner_property
GROUP BY owner_id
HAVING COUNT(property_id) > 1
returns all the owner_ids with more than 1 property_ids.
If there is a case of duplicates in the combination of owner_id and property_id then instead of COUNT(property_id) use COUNT(DISTINCT property_id) in the HAVING clause.
So join it to the other tables:
SELECT b.address, b.region, o.name
FROM (
SELECT owner_id
FROM owner_property
GROUP BY owner_id
HAVING COUNT(property_id) > 1
) t
INNER JOIN owner_property op ON op.owner_id = t.owner_id
INNER JOIN property p ON op.property_id = p.id_property
INNER JOIN owner o ON o.id_owner = op.owner_id
INNER JOIN building b ON p.building_id = b.id_building
ORDER BY op.owner_id, op.property_id ASC;
Always qualify the column names with the table name/alias.
You can try to use a correlated subquery that counts the ownerships with EXISTS in the WHERE clause.
SELECT b1.address,
b1.region,
o1.name
FROM owner_property op1
INNER JOIN owner o1
ON o1.id_owner = op1.owner_id
INNER JOIN property p1
ON p1.id_property = op1.property_id
INNER JOIN building b1
ON b1.id_building = p1.building_id
WHERE EXISTS (SELECT ''
FROM owner_property op2
WHERE op2.owner_id = op1.owner_id
HAVING count(*) > 1);

Postgresql : How to join with multiple cross-reference table?

I've seen a lot of post on multiple JOIN but it didn't help me in my case.
Consider that I have three tables and two cross-reference tables. That's the difference with the others posts where they had multiple tables but one cross-reference table in the FROM.
Table1 -> cross-ref1 <- table2 -> cross-ref2 <- table3
My version of Postgresql is : 9.0.11, and I'm working with W7 64 bits.
My request is the following stuff :
Select [columns] from cross-ref1, cross-ref2
INNER JOIN table1 ON table1.id_table1=cross-ref1.ref_id_table1
INNER JOIN table2 ON table2.id=cross-ref1.ref_id_table2
INNER JOIN table2 On table2.id_table2=cross-ref2.ref_id_table2
INNER JOIN table3 ON table3.id_table3=cross-ref2.ref_id_table3
The error message is : "Table name is specified more than once."
Can you explain me the error ?
Thanks
Cross-reference tables need separate columns for each side of the reference. An xref table with just one column makes no sense, as it can only refer to rows with the same ID on each side.
A typical setup would be:
CREATE TABLE a (
id integer primary key,
avalue text not null
);
CREATE TABLE b (
id integer primary key,
bvalue text not null
);
CREATE TABLE ab (
a_id integer references a(id),
b_id integer references b(id),
PRIMARY KEY(a_id, b_id)
);
Given sample data:
INSERT INTO a(id, avalue) VALUES
(1, 'a1'), (2, 'a2'), (3, 'a3'), (4, 'a4');
INSERT INTO b(id, bvalue) VALUES
(41, 'b1'), (42, 'b2'), (43, 'b3');
INSERT INTO ab(a_id, b_id) VALUES
(1, 41), (1, 42), (2, 43);
You'd find the pairings of a and b with:
SELECT avalue, bvalue
FROM a
INNER JOIN ab ON (a.id = ab.a_id)
INNER JOIN b ON (b.id = ab.b_id);
The crucial thing here is that you're joining on ab.a_id on the a side, and ab.b_id on the b side. Observe demo here: http://sqlfiddle.com/#!12/3228a/1
This is pretty much "many-to-many table relationships 101", so it might be worth doing some more study of introductory SQL and relational database tutorials and documentation.
You can't use the same table name twice (table2). In this case you need to use aliases like t1, t2a, t2b, ...
SELECT
...
FROM
table1 AS t1
INNER JOIN table2 AS t2a
ON t2a.id= ...
INNER JOIN table2 AS t2b
ON t2b.id= ...
INNER JOIN table3 AS t3
ON t3.id= ...
...
Now you can join whatever you want, how many times you want etc.
You have to explain what result you want to have. For example the following SQL is valid from syntax point of view, not sure about business point of view:
-- this will create sample data with 5 tables
with
crossref1(ref_id) as (VALUES (1),(2),(3)),
crossref2 (ref_id) as (VALUES (2),(3),(4)),
table1 (ref_id) as (VALUES (3),(4),(5)),
table2 (ref_id) as (VALUES (1),(2),(3)),
table3 (ref_id) as (VALUES (1),(2),(3))
-- valid SQL based on your example
select * from
crossref1
cross join crossref2
join table1 on table1.ref_id=crossref1.ref_id
join table2 as t2_1 on t2_1.ref_id=crossref1.ref_id
join table2 as t2_2 on t2_2.ref_id=crossref2.ref_id
join table3 on table3.ref_id=crossref2.ref_id
With your SQL there are two problems:
You have two references to table2, you have to add alias
You have to use cross join syntax instead of ,
If you would like to understand how with works (how I created sample data), PostgreSQL has excellent documentation on this.

Join tables query in SQL Server 2012

I have two tables like below:
TableA --> categoryId(pk), categoryParentId, catName
TableB --> empId(pk), categoryId, empName, empDesignation
I want to get all catName with respective categoryId from TableA where categoryId=2 of TableB is equal to categoryParentId=2 of TableA. Please help.
Result:
1002 SE
1003 MD
Something like this?
SELECT DISTINCT catName FROM TABLEA WHERE categoryParentId IN (SELECT DISTINCT categoryID from TABLEB);
I hope this query will fulfill your need
SELECT TABLEA.CATNAME AS CATEGORY
from TABLEB INNER JOIN TABLEA
ON TABLEA.CATEGORYPARENTID = TABLEB.CATEGORYID
Solution with INNER JOIN:
select TableA.catName
from TableA
inner join TableB on TableA.categoryParentId = TableB.categoryId
Using INNER JOIN is the recommended way to use for joining tables (as opposed to SELECT ... FROM TableA, TableB ...)
See:
INNER JOIN ON vs WHERE clause
(this question was actually about MySql, but the answers say that it's the same for SQL Server)
Difference in INNER join and cartesian join in SQL Server
Answering your comment (I assume that you wanted the categoryId from TableA):
select TableA.catName, TableA.categoryId
from TableA
inner join TableB on TableA.categoryParentId = TableB.categoryId
where TableB.categoryId = 2
another method...
SELECT
catname
from
tablea a INNER JOIN
tableb b ON
a.categoryParentID = b.categoryID
group by
catname
This should do the trick
SELECT tableA.catName
FROM tableA, tableB
WHERE tableB.categoryId = table1.categoryParentId
AND tableB.categoryId = 2;
If you want the unique catNames, you can use
SELECT distinct tableA.catName
FROM tableA, tableB
WHERE tableB.categoryId = table1.categoryParentId
AND tableB.categoryId = 2;