SQL Server hierarchy, selecting parent nodes for distinct IDs - sql

Stuck on this hierarchy problem, so here goes.
I have the following hierarchy table, which has been truncated.
The hierarchy has been joined to another table on the 'codes' column, with the following sample result. Let's call this table1.
For each distinct ID in table1, I want to utilize the hierarchy to find a parent, if it exists.
For example, under the codes column, 18 is the parent of 19.
I would like to fold or group the 19 with 18 and eliminate that row.
The desired result is something like this.
This does sort of what I want, using the GetAncestor method:
SELECT A.OrgNode, A.Codes, A.ID, B.OrgNode, B.Codes, B.ID FROM table1 A INNER JOIN table1 B ON A.OrgNode.GetAncestor(1) = B.OrgNode WHERE A.ID = B.ID

This self-join, with the GetAncestor function, did what I wanted it to do, with the 'where' on the same ID.
SELECT A.OrgNode, A.Codes, A.ID, B.OrgNode, B.Codes, B.ID FROM table1 A INNER JOIN table1 B ON A.OrgNode.GetAncestor(1) = B.OrgNode WHERE A.ID = B.ID

Related

Distinct IDs from one table for inner join SQL

I'm trying to take the distinct IDs that appear in table a, filter table b for only these distinct IDs from table a, and present the remaining columns from b. I've tried:
SELECT * FROM
(
SELECT DISTINCT
a.ID,
a.test_group,
b.ch_name,
b.donation_amt
FROM table_a a
INNER JOIN table_b b
ON a.ID=b.ID
ORDER by a.ID;
) t
This doesn't seem to work. This query worked:
SELECT DISTINCT a.ID, a.test_group, b.ch_name, b.donation_amt
FROM table_a a
inner join table_b b
on a.ID = b.ID
order by a.ID
But I'm not entirely sure this is the correct way to go about it. Is this second query only going to take unique combinations of a.ID and a.test_group or does it know to only take distinct values of a.ID which is what I want.
Your first and second query are similar.(just that you can not use ; inside your query) Both will produce the same result.
Even your second query which you think is giving you desired output, can not produce the output what you actually want.
Distinct works on the entire column list of the select clause.
In your case, if for the same a.id there is different a.test_group available then it will have multiple records with same a.id and different a.test_group.

join or merge two table based on id merge

I have two tables:
I am looking for the results like mentioned in the last.
I tried union (only similar col can be merged), left join, right join i am getting repeated fields in Null areas what can be other options where i can get null without column repeating
A full join would get all results from both tables.
select
A.ID,
A.ColA,
A.ColB,
B.ColC,
B.ColD
from TableA A
full join Table B on A.ID = B.ID
Here is a good post to understand joins
You can try distinct:
select distinct * from
tableA a,
tableB b
where a.id = b.id;
It will not give any duplicate tuples.

Can the order of Inner Joins Change the results o a query

I have the following scenario on a SQL Server 2008 R2:
The following queries returns :
select * from TableA where ID = '123'; -- 1 rows
select * from TableB where ID = '123'; -- 5 rows
select * from TableC where ID = '123'; -- 0 rows
When joining these tables the following way, it returns 1 row
SELECT A.ID
FROM TableA A
INNER JOIN ( SELECT DISTINCT ID
FROM TableB ) AS D
ON D.ID = A.ID
INNER JOIN TableC C
ON A.ID = C.ID
ORDER BY A.ID
But, when switching the inner joins order it does not returns any row
SELECT A.ID
FROM TableA A
INNER JOIN TableC C
ON A.ID = C.ID
INNER JOIN ( SELECT DISTINCT ID
FROM TableB ) AS D
ON D.ID = A.ID
ORDER BY A.ID
Can this be possible?
Print Screen:
For inner joins, the order of the join operations does not affect the query (it can affect the ordering of the rows and columns, but the same data is returned).
In this case, the result set is a subset of the Cartesian product of all the tables. The ordering doesn't matter.
The order can and does matter for outer joins.
In your case, one of the tables is empty. So, the Cartesian product is empty and the result set is empty. It is that simple.
As Gordon mentioned, for inner joins the order of joins doesn't matter, whereas it does matter when there's at least one outer join involved; however, in your case, none of this is pertinent as you are inner joining 3 tables, one of which will return zero rows - hence all combinations will result in zero rows.
You cannot reproduce the erratic behavior with the queries as they are shown in this question since they will always return zero records. You can try it again on your end to see what you come up with, and if you do find a difference, please share it with us then.
For the future, whenever you have something like this, creating some dummy data either in the form of insert statements or in rextester or the like, you make it that much easier for someone to help you.
Best of luck.

Slow performance query

I'm having a slow query performance and sometimes it came to an error of "Can't allocate space for object 'temp work table'"
I have 2 tables and 1 view. The first two tables have an left join and the last view will do a sub query. Below is the sample query.
SELECT a.*
FROM Table1 a LEFT JOIN Table2 b ON a.ID = b.ID
WHERE a.ID (SELECT ID
FROM View1).
The above query is very slow. BUT when I used a #temp table it becomes faster.
SELECT ID
INTO #Temp
FROM View1
SELECT a.*
FROM Table1 a LEFT JOIN Table2 b ON a.ID = b.ID
WHERE a.ID IN (SELECT ID
FROM #Temp)
Could someone explain why the first sql statement is very slow? and kindly give me an advise like adding new index?
Note: The first query statement cannot be altered or modified. I used only the second query statement to show to my team that if we put the 3rd table into temporary table and used it, makes faster.
Basically in the first query you are accessing the view for each and every row, and in turn the view is executing it's query.
In the second one you are executing the view's query just once and using the returned results through the temp table.
Try:
SELECT a.*
FROM Table1 a LEFT JOIN Table2 b ON a.ID = b.ID,
(SELECT ID
FROM View1) c
WHERE a.ID = c.ID;

Select returns the same row multiple times

I have the following problem:
In DB, I have two tables. The value from one column in the first table can appear in two different columns in the second one.
So, the configuration is as follows:
TABLE_A: Column Print_group
TABLE _B: Columns Print_digital and Print_offset
The value from the different rows and Print_group column of the Table_A can appear in one row of the Table_B but in different column.
I have the following query:
SELECT DISTINCT * FROM Table_A
INNER JOIN B ON (Table_A. Print_digital = Table_B.Print_group OR
Table_A.Print_offset = Table_B.Print_group)
The problem is that this query returns the same row from the Table_A two times.
What I am doing wrong? What is the right query?
Thank you for your help
If I'm understanding your question correctly, you just need to clarify your fields to come from Table_A:
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
EDIT:
Given your comments, looks like you just need SELECT DISTINCT B.*
SELECT DISTINCT B.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
I've still another question... first,to be clear, the right query version is
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group.
If I want it returns also one column from the B table it again returns duplicate rows. My query (the bad one) is the following one:
SELECT DISTINCT A.*, B.Id
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group