SQL Server cross a view with a set based on hierarchy - sql

I have a view in my SQL Server database which basically holds hierarchical information between some records based on id values of type int. A simple representation is as follows:
ID Parent_ID
1 NULL
2 1
3 2
4 NULL
5 4
By using this view I am trying to generate another view. I want all records that derive from ID=1 (which are 1, 2 and 3) to be crossed with a set, while other records (4, 5) be crossed another set. As an example crossing all records that derive from ID=1 with set (1,2) and crossing other records with set 3, I want a view as follows:
ID Value
1 1
1 2
2 1
2 2
3 1
3 2
4 3
5 3

Related

distinct value row from the table in SQL

There is a table with values as below,
Id Value
1 1
2 1
3 2
4 2
5 3
6 4
7 4
now need to write a query to retrieve value from the table and output should look as
ID Value
1 1
3 2
5 3
6 4
any suggestion ?
The query you want is nothing to do with being distinct, it's a simple aggregation of value with the minimum ID for each:
select Min(id) Id, value
from table
group by value

SQL Calculations With Multi-Group Affiliations

I'm attempting to have a function or view that is able to calculate and roll up various counts while being able to search on a many to many affiliation.
Here is an example data set:
Invoice Table:
InvoiceID LocationID StatusID
1 5 1
2 5 1
3 5 1
4 5 2
5 7 2
5 7 1
5 7 2
Group Table:
GroupID GroupName
1 Group 1
2 Group 2
GroupToLocation Table:
GroupToLocationID GroupID LocationID
1 1 5
2 2 5
3 2 7
I have gotten to the point where I could sum up the various statuses per location and get this:
LocationID Status1 Status2
5 3 1
7 1 2
Location 5 has 3 Invoices with a status of 1, and 1 invoice with a status of 2 while Location 7 has 1 status 1 and 2 status 2
There are two groups, and Location 5 is in both, while Location 7 is only in the second. I need to be able to set it up where I can append a where statement like this:
select * from vw_GroupCounts
where GroupName = 'Group 2'
or
select Invoice, SUM(*) from vw_GroupCounts
where GroupName = 'Group 2'
And that result in only getting Location 7. Whenever I do this, as I have to use left joins or something along those lines, the counts are duplicating for each group the the Location is affiliated with. I know I could do something along the lines of a subquery and pass in the GroupName into that, but the system I am working with uses a dynamic query builder that appends WHERE statements based on user input.
I don't mind using view, or functions, or any number of functions inside of functions, but I hope there is a way to do what I'm looking for.
Since locations 5 and 7 are in Group 2, if you search for group 2 in the where clause after joining all the tables, then you would get all records in this case, this isn't duplication, just the way the data is. A different join wouldn't change this, only changing the data. Let me know if I am misunderstanding something though.
Here is how you would join them to do that search.
Here it is with your first example of the location and status count.

Adding Auto Increment Value to Column in relation to Duplicate values in Another Column

I have a large table (3 million rows and about 12 columns). I have one column that can contain duplicate values - this is my "ID" column. I have a second column "NUM_ID" that I would like to have it start at the value of 1 for every unique "ID". Then - if I run into a duplicate value - "NUM_ID" would then bump up one value (to 2) and so on. For example:
ID NUM_ID
1 1
2 1
2 2
2 3
3 1
3 2
4 1
5 1
5 2
5 3
5 4
Again, "ID" is pre-populated, I cannot change this column and its values. My "NUM_ID" column is currently empty - I'm hoping there is a sql command I can use to populate the column as shown above? I've tried using Python but updating 3M rows is taking a long time. Also, if it matters, I am using PostGresSQL.
Help? Thanks!
If you are Using SQL Server then You Should Use ROW_NUMBER() as below :
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) NUM_ID FROM #TM
Result :
ID NUM_ID
1 1
2 1
2 2
2 3
3 1
3 2
4 1
5 1
5 2
5 3
5 4

Oracle SQL index rows based on group by/ parent row

I have 1 table, which refers by value to rows in the same table
Example table:
ID PARENT_ID NAME
1 0 john
2 1 jane
3 2 smigy
4 2 gujo
5 1 duby
6 1 ruby
7 5 foo
8 2 bar
9 3 baz
10 3 qux
The root-parent has parent 0 (just so it wouldn't be null), in this case there's
1 root-parent - parent(0)=1.
root-parent has 1lvl children - parent(1)=2;5;6.
1lvl children has 2lvl children - parent(2)=3;4;8. parent(5)=7. parent(6) has nothing.
2lvl children has 3lvl children - parent(3)=9;10. parent(4) has nothing. parent(8) has nothing.
There is no lvl4 children or anything with depth beyond 4.
And I need to create a script (presumably SQL query - need to avoid function/procedure/etc.) that would index rows based on their position under their parent.
Just like if I'd select all root-parent's and get (rownum-1)
The goal table should look like this:
ID PARENT_ID NAME ROW_INDEX
1 0 john 0
2 1 jane 0
3 2 smigy 0
4 2 gujo 1
5 1 duby 1
6 1 ruby 2
7 5 foo 0
8 2 bar 2
9 3 baz 0
10 3 qux 1
I'm planing to add this column and thus the query will be executed only once. I've played by selecting seperate depth rows, but then I don't really know how to count inside/between group by (even if that is possible).
P.S. A better/good column name suggestion would also be very appreciated.
User row_number()
select mt.*, row_number() over(partition by parent_id order by id) - 1 as rn
from MyTable mt

Oracle: Usage the CONNECT BY statement without START WITH

I'm having some difficulties in the usage of the CONNECT BY statement with Oracle. I have no problem in writing the query for 1 given record (using START WITH) but I'm looking for a possibility to create an extract.
Data
1
2
3
4
5
6
Table
ID PARENT_ID
1 2
1 5
1 6
2 3
2 4
What I need is a table which would be filled with the following information/records.
Desired Output
ID PARENT_ID
1 2
1 3
1 4
1 5
1 6
2 3
2 4
If I use the following query
SELECT PARENT_ID
FROM TABLE
START WITH ID = 1
CONNECT BY NOCYCLE PRIOR ID = PARENT_ID
I will have the following result
2
3
4
5
6
This is effectively the parent_id's which I am looking for for ID 1.
If I remove the start with I have the following list
2
3
4
5
6
3
4
I've tried to add the ID in the statement but that did not work either. Any idea if it's possible to have such an output?
You forgot the prior keyword. You want to connect the parent_id to the id of the previous record. (Could be the other way around, but you'll notice that fast enough. ;-) )
SELECT ID
FROM TABLE
START WITH ID = 1
CONNECT BY prior ID = PARENT_ID