MySQL Stored Procedure Design Problem V2. Recusion or Hierarchy? - mysql

Suppose we have a table named Connected, with column node_1 and node_2, both integer type, and some data in it.
It looks like this:
`node_1` `node_2`
A B
C D
B C
B F
C W
D N
D Q
.
.
. Much much much more
.
What Im trying to do is expand this table, and then collect all relations. For instance, if we can travel from 'A' to 'Q' with path 'A-B-C-D-Q' ( defined by the old table, 'A-B, B-C, C-D, D-Q'), we say that 'A' and 'Q' can be connected, and insert this pair into new table.
Such that, the result table should looks like this:
`node_1` `node_2`
A B
A C
A D
A F
A N
A Q
A W
B C
B D
B F
B N
B Q
B W
C D
C N
C Q
C W
D Q
D N
I appreciate all helps !
Change the word "Node" to "Group",
"connected" to "contains", does it
sound more reasonable? Im Sorry for my
gramma or any other language related
problemssss :)

Same as my other solution, just use ASCII() around the character to the its ascii value in the SELECT.
MySQL Stored Procedure Design Problem. Recusion or Hierarchy?
PS. due to our conversation in the other question. Im getting the impression your really content of finding a imperative solution for this. Remember, SQL is a declarative language.

Related

SQL (mySQL) to find if there are cousins in some listed families

I need to list all titles that have items in libraries A, B and D
There could also be items in library C, but I don't have to care about that
I have this SQL-query - is there a smarter way to do this?
I guess the problem could be formulated as something like are there any cousins in those three listed familes?
(In real life I have to find items in 42 libraries, and the real question also involves reserves - so anything that makes the code shorter is appreciated)
SELECT DISTINCT b.biblionumber
FROM items i
LEFT JOIN biblio b ON (b.biblionumber=i.biblionumber)
WHERE i.homebranch = 'A'
AND EXISTS
(
select *
FROM items i2
WHERE i2.biblionumber = b.biblionumber
AND i2.homebranch = 'B'
)
AND EXISTS
(
select *
FROM items i3
WHERE i3.biblionumber = b.biblionumber
AND i3.homebranch = 'D'
)
Though your approach may performs the fastest, Yet you have to go for 42 searches, So You may try below query -
SELECT DISTINCT b.biblionumber
FROM items i
LEFT JOIN biblio b ON b.biblionumber=i.biblionumber
WHERE i.homebranch IN ('A', 'B', 'D', ...../* You Search List */)
GROUP BY i.homebranch
HAVING COUNT (DISTINCT homebranch) = 42;

Lookup two Display Names using the same Table on 1 unique assignment in SQL Tables

I am trying to write a query where two different UIDs need to lookup a Resource Name for both, but separately.
In other words, for each Task, there are resources assigned and one status manager. This converts in SQl to an Assignment, unique to a resource, but with the same status manager. However, no where in the database can one see the Status Manager's Name on a given assignment.
The assignment does have "TaskStatusManagerUID" available. The name of the Status Manager can be determined by tying it back to MSP_EPMResource table where TaskStatusManagerUID = ResourceUID.
The catch is, for my report, I need to be able to look at the ResourceUID and TaskstatusManagerUID and determine the names of each on the same assignment.
While I have been successful with a join to display the name for one or the other, I have not been able to determine how to show the name for both the Resource and TaskStatusManager.
This is an example of what I am trying to display (parentheses added for readability):
(AssignmentUID) (Task Name) (Resource Name) (Task Status Manager Name)
See more info below:
This is the code I have been working with, but have been unsuccessful:
Select top 100
c.[assignmentuid],
a.[taskname],
c.[resourceuid],
b.[resourcename],
a.[taskstatusmanageruid],
d.[StatusManager]
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmAssignment] c
join [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmTask_UserView] a
on a.[TaskUID] = c.[TaskUID]
join [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b
on b.[ResourceUID] = c.[ResourceUID]
join (select b.resourcename StatusManager
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b) d
on d.[StatusManager] = a.[taskstatusmanageruid]
group by
c.[assignmentuid],
a.[taskname],
c.[resourceuid],
b.[resourcename],
a.[taskstatusmanageruid],
d.[StatusManager]
Currently, I am getting "Conversion failed when converting from a character string to uniqueidentifier."
On your joins you have on a.[TaskUID] = c.[TaskUID], on b.[ResourceUID] = c.[ResourceUID], and on d.[StatusManager] = a.[taskstatusmanageruid], of which, I am assuming that the last one is causing you the issue. Try instead
join (select b.resourcename StatusManager
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b) d
on d.[StatusManager] = CONVERT(CHAR, a.[taskstatusmanageruid])
This will convert the GUID contained in taskstatusmanageruid to a char string, allowing it to compare successfully.
You could also, instead of converting the value, cast the value CAST(a.[taskstatusmanageruid] AS CHAR
EDIT
Due to the nature of the GUID, you may not be able to convert/cast it to a char value, in which case you would need to convert/cast both fields to either varchar or nvarchar:
join (select b.resourcename StatusManager
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b) d
on CONVERT([N]VARCHAR, d.[StatusManager]) = CONVERT([N]VARCHAR, a.[taskstatusmanageruid])
OR
join (select b.resourcename StatusManager
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b) d
on CAST(d.[StatusManager] AS [N]VARCHAR) = CAST( a.[taskstatusmanageruid] AS [N]VARCHAR)
Thanks to Jeff Beese's extra set of eyes, it was enough for me to get the last piece in place!
Select top 100
c.[assignmentuid],
a.[taskname],
c.[resourceuid],
b.[resourcename],
a.[taskstatusmanageruid],
d.[StatusManager]
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmAssignment] c
join [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmTask_UserView] a
on a.[TaskUID] = c.[TaskUID]
join [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b
on b.[ResourceUID] = c.[ResourceUID]
join (select b.resourcename as StatusManager,
b.ResourceUID
from [PRJPROD_ProjectWebApp].[dbo].[MSP_EpmResource] b) d
on d.[resourceuid] = a.[taskstatusmanageruid]
group by
c.[assignmentuid],
a.[taskname],
c.[resourceuid],
b.[resourcename],
a.[taskstatusmanageruid],
d.[StatusManager]

Is there a way with nearest neighbour search in MySQL?

I have the following table:
CREATE TABLE numbert_t ( v DOUBLE , id INTEGER, INDEX(v) )
and I want to do a query with a paremeter q that sorts the points in distance abs( q - v ). For example
SELECT v, id, ABS( q - v ) AS d FROM number_t ORDER BY d
I tried the query above and this one:
SELECT v, id, (v - q) AS d FROM numbers_t WHERE (v - q) > 0
ORDER BY d
I also tried slight variations of the above:
SELECT v, id, (v - q) AS d FROM numbers_t WHERE v > q ORDER BY v
They are not equivalent, but I don't mind to do two queries and have two independent cursors. However, in all cases EXPLAIN says that filesort, no indices would be used. Can I get MySQL to somehow use indices for this problem?
Did you try:
SELECT MIN(v), id FROM number_t WHERE v >= q
UNION
SELECT MAX(v), id FROM number_t WHERE v < q
MySQL specific, not standard, because of the id. But the id might be retrieved after you have gotten exact values.
You can use the spatial extension and a point datatype. Then you can use a proximity search for example when a point is inside a bounding box. You can also use my quadkey library. It uses a hilbert curve and a mercator projection. You can download my php class hilbert curve # phpclasses.org.

Filtering before join to avoid "multi-part identifier could not be bound" error

I am using SQL Server 2008 and trying to write a query in a SSIS Package data flow task to read data from one data base based on the result set from another DB.
I have multiple tables A, B, C, D, E etc and I am trying to write a select that joins these tables and get the data after a filter. I am getting a "multi-part identifier could not be bound" error on the following query
SELECT
A.1 as A1,
A.2 as A2,
A.3 as A3,
B.1 as B1,
(Select C.1 from C
left join cc on c.2 = cc.2
where C.x = A.x) as C1,
(Select D.1 from D where D.x = A.x) as D1,
E.4 as E4
FROM A
left join B on B.Y = A.Y
inner join C on C.Y = A.Y
inner join D on D.Y = C.X
left join E on E.Y = D.Z AND E.Z = 'ZZZZ'
WHERE A.P = ?
The general structure of the query is as above and the query runs fine if I remove the where clause completely or give a simple "WHERE A.P = 'PPPP'". It appears simple enough and I am not using any data from the sub queries in the where clause. What am I doing wrong?
This error means that the reference cannot be bound to an object. However, it doesn't refer to the column part of the expression, just the part before that.
So, if P is not column in A, then A.P will generate an error like "Column not found". If A is not defined in the from clause, then A.P will give you the `multi-part identifier not found error".
A common reason is misusing an alias. If you have code like this:
from TableA a
where TableA.col . . .
Then you will get the error. Although TableA is in the from clause, it is known in the query by its alias A, not by the table name. This can also happen because you have mistyped a table name, schema name, database name, or server name in an expression.

MySQL: JOIN query on 3 tables

I am currently learning MySQL and want to write a simple dictionary application.
Currently I have 3 tables:
Language1:
ID | Word
Language2:
ID | Word
Dict:
ID_Lang1 | ID_Lang2
Now I am struggling to make a query that looks in both language tables for the word and via the dict table finds the corresponding word in the other language.
What I was trying was like:
select lang1.ID, lang2.ID from Language1, Language2 WHERE lang1.word OR lang2.word = 'Random'
and to join this somehow together with the Dict table, but could not make it work.
Hope someone will enlighten me!
Maybe something like this?
SELECT *
FROM `dict` d
LEFT JOIN `language1` l1 ON d.`id_lang1` = l1.`id`
LEFT JOIN `language2` l2 ON d.`id_lang2` = l2.`id`
WHERE
l1.`word` LIKE 'random'
OR l2.`word` LIKE 'random'
Performance of query will get hit as Dict becomes larger, but this is just one way to do it:
SELECT L1.ID, L2.ID
FROM Language1 AS L1
INNER JOIN Dict AS D ON D.ID_Lang1 = L1.ID
INNER JOIN Language2 AS L2 ON D.ID_Lang2 = L2.ID
WHERE L1.Word = 'Random'
OR L2.Word = 'Random'