SQL: Linking Multiple Rows in Table Based on Data Chain in Select - sql

I'm trying to create a select statement which will return all linked rows based on a "LINK_SEQUENCE" column. The column however, only links two rows together. A simple query to combine the two makes perfect sense to me. However, in the case that three or more links in the "chain" are present, I want to make sure that all codes are returned.
How would I go about returning something similar to this when only handing the query one of the codes involved? EX: 3245.
Not sure if it much matters in this situation, but this is for an Oracle database. Thank you all very much!
Source data from SQL Fiddle:
ID CODE LINK_SEQUENCE NAME
1 3267 1 Potato
2 3245 1 Potato
3 3245 2 Potato
4 3975 2 Potato
5 3975 3 Potato
6 5478 3 Potato
7 2368 4 Apricot
8 4748 4 Apricot
9 8957 (null) Carrot

SELECT * FROM LinkedTable lt
WHERE ft.link_sequence IN
( SELECT link_sequence FROM LinkedTable WHERE code = 3245 AND link_sequence IS NOT NULL )
ORDER BY ft.ID;
See my SQL Fiddle DEMO.
SECOND ATTEMPT:
SELECT DISTINCT *
FROM LinkedTable
START WITH code = 3245
CONNECT BY NOCYCLE
PRIOR code = code AND PRIOR link_sequence+1 = link_sequence OR
PRIOR code <> code AND PRIOR link_sequence = link_sequence
ORDER BY link_sequence, code
;
Updated SQL Fiddle with this code. Please try to break it.
Based on your data (starting with 3245) it gives the following chain:
ID CODE LINK_SEQUENCE NAME
2 3245 1 Potato
1 3267 1 Potato
3 3245 2 Potato
4 3975 2 Potato
5 3975 3 Potato
6 5478 3 Potato

Related

Select maximum value where another column is used for for the Grouping

I'm trying to join several tables, where one of the tables is acting as a
key-value store, and then after the joins find the maximum value in a
column less than another column. As a simplified example, I have the following three tables:
Documents:
DocumentID
Filename
LatestRevision
1
D1001.SLDDRW
18
2
P5002.SLDPRT
10
Variables:
VariableID
VariableName
1
DateReleased
2
Change
3
Description
VariableValues:
DocumentID
VariableID
Revision
Value
1
2
1
Created
1
3
1
Drawing
1
2
3
Changed Dimension
1
1
4
2021-02-01
1
2
11
Corrected typos
1
1
16
2021-02-25
2
3
1
Generic part
2
3
5
Screw
2
2
4
2021-02-24
I can use the LEFT JOIN/IS NULL thing to get the latest version of
variables relatively easily (see http://sqlfiddle.com/#!7/5982d/3/0).
What I want is the latest version of variables that are less than or equal
to a revision which has a DateReleased, for example:
DocumentID
Filename
Variable
Value
VariableRev
DateReleased
ReleasedRev
1
D1001.SLDDRW
Change
Changed Dimension
3
2021-02-01
4
1
D1001.SLDDRW
Description
Drawing
1
2021-02-01
4
1
D1001.SLDDRW
Description
Drawing
1
2021-02-25
16
1
D1001.SLDDRW
Change
Corrected Typos
11
2021-02-25
16
2
P5002.SLDPRT
Description
Generic Part
1
2021-02-24
4
How do I do this?
I figured this out. Add another JOIN at the start to add in another version of the VariableValues table selecting only the DateReleased variables, then make sure that all the VariableValues Revisions selected are less than this date released. I think the LEFT JOIN has to be added after this table.
The example at http://sqlfiddle.com/#!9/bd6068/3/0 shows this better.

MS SQL Recursive Stored Procedure To Group Based Off Of User Attributes

I'm having a bit of trouble finding the best way to group users together based off of their attributes.
Here's a simplified version of some user data:
ID | First Name | Last Name | Address | Email | Phone 1 | Phone 2 | Phone 3 |
-----------------------------------------------------------------------------
1 Bob Smith Addy 1 a#a 1 2 3
2 Susan Q Addy 2 b#b 4 5 6
3 Robert Smith a#a 1
4 Susie Quinn Addy 2
5 Ryan Foo Addy 3 c#c
6 Pat Bar Addy 4
7 Patrick Bar Addy 4 1 2 3
From that, I can tell that the grouped items will look like:
1,3 (Matched on email)
2,4 (Matched on address)
5 (no matches)
6,7 (Matched on Address and last name)
1,7 (Matched on all three phone numbers)
I'm able to get this far with the stored procedure I've written. This results in 2.6 million results. Now, the next step I need to take is to merge these into non-duplicate groups... which should look something like this:
1,3,6,7
2,4
5
I've tested out a cursor query but, after 30 minutes of execution, it hadn't finished. So my question is this: what's the best/most efficient way to turn my 1 to 1 matches into one to many matches?

Special group by (based on succeeding values) in SQL

I would like to perform a special group by statement, in other programming languages I would use some kind of loop, but I have no idea on how to tackle this using sql. Hope that you guys can be of some help. Bit of sample data
NR date Code
2 1-1-2013 6
2 1-1-2013 6
2 3-1-2013 6
2 4-1-2013 7
2 5-1-2013 6
2 5-1-2013 5
3 1-1-2013 1
3 2-1-2013 1
3 2-1-2013 6
3 3-1-2013 7
I would like to do a group by on NR and Code. However I don't want to group non-succeeding Code's (they are sorted on NR and date). The desired output will make it clear i think:
NR Code #
2 6 3
2 7 1
2 6 1
2 5 1
3 1 2
3 6 1
3 7 1
After this I would like to cast it to this format (could be another question, but illustrates my need for a solution for the problem above):
NR Code_string #_string
2 6,7,6,5 3,1,1,1
3 1,6,7 2,1,1
If I did not provide a good example, please tell, this is my first question for sql (learned alot of R using SO)
select NR, Code, count(*) from yourdatabasename
group by NR, Code
order by NR, Code
This command should satisfy yor first desired output.

SQL comparing two tables with common id but the id in table 2 could being in two different columns

Given the following SQL tables:
Administrators:
id Name rating
1 Jeff 48
2 Albert 55
3 Ken 35
4 France 56
5 Samantha 52
6 Jeff 50
Meetings:
id originatorid Assitantid
1 3 5
2 6 3
3 1 2
4 6 4
I would like to generate a table from Ken's point of view (id=3) therefore his id could be possibly present in two different columns in the meetings' table. (The statement IN does not work since I introduce two different field columns).
Thus the ouput would be:
id originatorid Assitantid
1 3 5
2 6 3
If you really just need to see which column Ken's id is in, you only need an OR. The following will produce your example output exactly.
SELECT * FROM Meetings WHERE originatorid = 3 OR Assistantid = 3;
If you need to take the complex route and list names along with meetings, an OR in your join's ON clause should work here:
SELECT
Administrators.name,
Administrators.id,
Meetings.originatorid,
Meetings.Assistantid
FROM Administrators
JOIN Meetings
ON Administrators.id = Meetings.originatorid
OR Administrators.id = Meetings.Assistantid
Where Administrators.name = 'Ken'

MS Access CrossTab query - across 3 tables

I have the following 3 tables:
1) Sweetness Table
FruitIndex CountryIndex Sweetness
1 1 10
1 2 20
1 3 400
2 1 50
2 2 123
2 3 1
3 1 49
3 2 40
3 3 2
2) Fruit Name Table
FruitIndex FruitName
1 Apple
2 Orange
3 Peaches
3) Country Name Table
CountryIndex CountryName
1 UnitedStates
2 Canada
3 Mexico
I'm trying to perform a CrossTab SQL query to end up with:
Fruit\Country UnitedStates Canada Mexico
Apple 10 20 400
Orange 50 123 1
Peaches 49 40 2
The challenging part is to label the rows/columns with the relevant names from the Name tables.
I can use MS Access to design 2 queries,
create the joins the fruit/country names table with the Sweetness table
perform crosstab query
However I'm having trouble doing this in a single query. I've attempted nesting the 1st query's SQL into the 2nd, but it doesn't seem to work.
Unfortunately, my solution needs to be be wholly SQL, as it is an embedded SQL query (cannot rely on query designer in MS Access, etc.).
Any help greatly appreciated.
Prembo.
How about:
TRANSFORM First(Sweetness.Sweetness) AS FirstOfSweetness
SELECT Fruit.FruitName
FROM (Sweetness
INNER JOIN Fruit
ON Sweetness.FruitIndex = Fruit.FruitIndex)
INNER JOIN Country
ON Sweetness.CountryIndex = Country.CountryIndex
GROUP BY Fruit.FruitName
PIVOT Country.CountryName;
I hate to rely on an outside post and present it as my answer, but this is a pretty steep topic and I can't do it justice. So I suggest you look at this article.