parse multiline varchar field into rows (T-sql) - sql

I am making a report in SSRS. Database contains table "Project" with a "Notes" field which is formated by users in this way:
#Completed
-line 1 description
-line 2 description
-line3 and so on
#Planned
-line 1 etc.
#Risks
- line1 ...etc
There are always only those 3 categories and in that order. Bullet points can be from 0 to unlimited (but i never seen more than 10)
I would like to get output(dataset) in format (so I can group them in tablix):
ProjectID, Maincategory, itemID, subcategories.
For example
1 | Completed | 1 | line1
1 | Completed | 2 | line2
1 | Completed | 3 | line3
...
1 | Planned | 1 | Line1
...
1 | Risks | 1 | line1
...
I cant change source DB so I cant create stored procedure, it should be regular query.
I looked at various solutions with CTE recursions but I just cant figure out how they work in oreder to change them for my case.
Thank you!

Related

SQL Nested Case When with numeric check

I'm trying to create a "filter" with SQL.
I have a table named ARTICLE like this :
CODE | NAME | QUANTITY |
_______________|_________________|_______________
0020717270084 | MANGO FRUIT 1L | 3 |
0884394000774 | ALOE VERA 50CL | 4 |
16 | CHEWING GUM | 10 |
IGLOO | IGLOO ICE | 5 |
I want to do a SELECT with a verification on CODE.
If CODE is a number AND has a length of 8 OR 10 OR 13 digits, i display CODE ELSE i have to display * before CODE (simple concat).
I can do CASE WHEN but this one is a little bit tricky for me.
Thanks for your help.
You would do this with a case statement. Databases do the checks differently. The following is an approach using SQL Server:
select (case when len(code) in (8, 10, 13) and code not like '%[^0-9]%'
then code
else '*' + code
end)

Multiples of a number oracle SQL

How do you check if the content of a field is a multiple of 2 in oracle sql
n_id | n_content
-------------------------
1 | Balloon
2 | Drill
3 | Cup
4 | Bottle
5 | Pencil
6 | Ball
I have tried:
select*from num_w where (n_id%2>0);
and also
select*from num_w where n_id%2=0;
Neither of these worked
Wasn't this multiple of 5 a few seconds ago? :)
Anyway, in Oracle I believe the query would be:
select * from num_w where MOD(n_id,2) = 0;

Pairwise testing: How to create the table?

Hello I have doubt regarding how to create the table for the pairwise testing.
For example if I have three parameter which can each attain two different values. How do I create a table of input with all possible combination then? Would it look something like this?
| 1 2 3
-----------
1 | 1 1 1
2 | 1 2 2
3 | 1 1 2
4 | 1 2 1
Does each parameter corresponds to each column?
However since I have 3 parameter, which each can take 2 different value. The number of test cases should be 2^3 isn't it?
There's a good article with links to some useful tools here:
http://blog.josephwilk.net/ruby/pairwise-testing-with-cucumber.html
For the parameters: each column is a parameter, and each row is a possible combination. Here is the table:
| 1 2 3
-----------
1 | 1 1 1
2 | 2 1 1
3 | 1 2 1
4 | 1 1 2
5 | 2 2 1
6 | 2 1 2
7 | 1 2 2
8 | 2 2 2
so 2^3=8 possible combinations as you can see :)
For the values: each column is a value, and each row is a possible combination:
| 1 2
--------
1 | 1 1
2 | 2 1
3 | 1 2
4 | 2 2
They are 2^2=4 possible combinations. Hope it helps.
1) Please note that pair-wise testing is not about scanning exhaustively all possible combination of values of all parameters. Firstly, such a scanning would give you an enormous amount of test cases that almost no existing system could be able to run all of them.
Secondly, pair-wise testing for a software system is based on the hope that the two parameters having the highest number of possible values are the culprit for the highest percentage of faults of that system.
This is of course only a hope and almost no rigorous scientific research has existed so far to prove that.
2) What I often see in the documentations discussing pair wise testing, like this is that the list of all possible values (aka the pair-wise test table) is not constructed in a well thought way. This creates confusions.
In your case, all the parameters have the same number of possible values (2 values), therefore you could choose any two parameters of those three to build the table. What you could pay attention is the ordering of the combination: you iterate first the top-right parameter, then the next parameter to the left, and so on, ...
Say if you have two parameters p1 and p2, p1 has two possible values apple and orange; and p2 has two possible values red and blue, then your pair-wise test table would be:
index| p1 p2
------------------
1 | apple red
2 | apple blue
3 | orange red
4 | orange blue

How to represent and insert into an ordered list in SQL?

I want to represent the list "hi", "hello", "goodbye", "good day", "howdy" (with that order), in a SQL table:
pk | i | val
------------
1 | 0 | hi
0 | 2 | hello
2 | 3 | goodbye
3 | 4 | good day
5 | 6 | howdy
'pk' is the primary key column. Disregard its values.
'i' is the "index" that defines that order of the values in the 'val' column. It is only used to establish the order and the values are otherwise unimportant.
The problem I'm having is with inserting values into the list while maintaining the order. For example, if I want to insert "hey" and I want it to appear between "hello" and "goodbye", then I have to shift the 'i' values of "goodbye" and "good day" (but preferably not "howdy") to make room for the new entry.
So, is there a standard SQL pattern to do the shift operation, but only shift the elements that are necessary? (Note that a simple "UPDATE table SET i=i+1 WHERE i>=3" doesn't work, because it violates the uniqueness constraint on 'i', and also it updates the "howdy" row unnecessarily.)
Or, is there a better way to represent the ordered list? I suppose you could make 'i' a floating point value and choose values between, but then you have to have a separate rebalancing operation when no such value exists.
Or, is there some standard algorithm for generating string values between arbitrary other strings, if I were to make 'i' a varchar?
Or should I just represent it as a linked list? I was avoiding that because I'd like to also be able to do a SELECT .. ORDER BY to get all the elements in order.
As i read your post, I kept thinking 'linked list'
and at the end, I still think that's the way to go.
If you are using Oracle, and the linked list is a separate table (or even the same table with a self referencing id - which i would avoid) then you can use a CONNECT BY query and the pseudo-column LEVEL to determine sort order.
You can easily achieve this by using a cascading trigger that updates any 'index' entry equal to the new one on the insert/update operation to the index value +1. This will cascade through all rows until the first gap stops the cascade - see the second example in this blog entry for a PostgreSQL implementation.
This approach should work independent of the RDBMS used, provided it offers support for triggers to fire before an update/insert. It basically does what you'd do if you implemented your desired behavior in code (increase all following index values until you encounter a gap), but in a simpler and more effective way.
Alternatively, if you can live with a restriction to SQL Server, check the hierarchyid type. While mainly geared at defining nested hierarchies, you can use it for flat ordering as well. It somewhat resembles your approach using floats, as it allows insertion between two positions by assigning fractional values, thus avoiding the need to update other entries.
If you don't use numbers, but Strings, you may have a table:
pk | i | val
------------
1 | a0 | hi
0 | a2 | hello
2 | a3 | goodbye
3 | b | good day
5 | b1 | howdy
You may insert a4 between a3 and b, a21 between a2 and a3, a1 between a0 and a2 and so on. You would need a clever function, to generate an i for new value v between p and n, and the index can become longer and longer, or you need a big rebalancing from time to time.
Another approach could be, to implement a (double-)linked-list in the table, where you don't save indexes, but links to previous and next, which would mean, that you normally have to update 1-2 elements:
pk | prev | val
------------
1 | 0 | hi
0 | 1 | hello
2 | 0 | goodbye
3 | 2 | good day
5 | 3 | howdy
hey between hello & goodbye:
hey get's pk 6,
pk | prev | val
------------
1 | 0 | hi
0 | 1 | hello
6 | 0 | hi <- ins
2 | 6 | goodbye <- upd
3 | 2 | good day
5 | 3 | howdy
the previous element would be hello with pk=0, and goodbye, which linked to hello by now has to link to hey in future.
But I don't know, if it is possible to find a 'order by' mechanism for many db-implementations.
Since I had a similar problem, here is a very simple solution:
Make your i column floats, but insert integer values for the initial data:
pk | i | val
------------
1 | 0.0 | hi
0 | 2.0 | hello
2 | 3.0 | goodbye
3 | 4.0 | good day
5 | 6.0 | howdy
Then, if you want to insert something in between, just compute a float value in the middle between the two surrounding values:
pk | i | val
------------
1 | 0.0 | hi
0 | 2.0 | hello
2 | 3.0 | goodbye
3 | 4.0 | good day
5 | 6.0 | howdy
6 | 2.5 | hey
This way the number of inserts between the same two values is limited to the resolution of float values but for almost all cases that should be more than sufficient.

SQL - Update table changing one column value based on another table

Sorry if the title is not as descriptive as it should be but it is kind of difficult to explain in one sentence what I am trying to do ;).
I have one table that links parent objects with its respective childs. And I have another table with all the objects (parents and childs) with its respectives images. However, the image is just set for the parents objects. I would like to update this last table and set the childs image the same image that is already set for its parent. Besides, as there is more than one image for each object, I would like to set one in particular, which I can know based on an attribute column.
My tables look something like:
RelationTable
child-id
parent-id
ImageTable
object-id
attribute-id
image-url
And here goes an example in order to clarify things:
RelationsTable
child-id | parent-id
3 | 1
4 | 1
5 | 2
ImageTable
object-id | attribute-id | image-url
1 | goodimage | image1.jpg
1 | badimage | image1b.jpg
2 | goodimage | image2.jpg
2 | badimage | image2b.jpg
3 | goodimage | no
3 | badimage | no
4 | goodimage | no
4 | badimage | no
5 | goodimage | no
5 | badimage | no
So, I would like to set the images of objects 3, 4 and 5 (child ones) to its respective parent images, but to the 'correct' ones, that is the images with 'goodimage' as attribute-id.
At the end it should look like:
1 | goodimage | image1.jpg
1 | badimage | image1b.jpg
2 | goodimage | image2.jpg
2 | badimage | image2b.jpg
3 | goodimage | image1.jpg
3 | badimage | no
4 | goodimage | image1.jpg
4 | badimage | no
5 | goodimage | image2.jpg
5 | badimage | no
Actually, I don't care if 'badimage' is set as well, but the important one is 'goodimage'.
I've been trying something like:
UPDATE ImageTable
SET image = (SELECT image-url FROM ImageTable WHERE ImageTable.object-id = RelationTable.parent-id AND ImageTable.attribute-id = 'goodimage')
WHERE ImageTable.object-id = RelationTable.child-id AND ImageTable.attribute-id = 'goodimage'
but it's not working since it is not correct SQL syntax. I don't know if I should use a variable (never used one) or if this can be done with just one SQL sentence.
Any help would be much appreciated.
something like this?
NOTES:
This could be merged into one
non-subquery statement but I was
lazy.
I did not test, expect typos
;WITH goodlist AS
(
SELECT child-id, image-url
FROM relationstable
left join imagetable on relationstable.child-id = relationstable.child-id and attribute-id = "goodimage"
)
UPATE imagetable
set imagetable.image-url =
(SELECT top 1 image-url from goodlist where child-id = imagetable.object-id)
WHERE imagetable.image-url = "no"
First of all, if the relation between parent and child is 1:n, why don't you just add that information to the same table? e.g. fieldname "parentid" (if it's empty/null it's only a parent). Benefit: you don't need an additional table and can easily create a hierarchy if needed.
And for the image, I guess you want to display this somewhere in your code, but it should be easier to just modify the SELECT to get the image-url of the parent is no image is given for the child. Benefit: no need to update the table when you get new entries and it would also be possible to for some child entries to have their own image (if needed).
edit: just noticed your new comment about the open-source project part, of course this makes it hard to change the database design. But maybe it's still easier to move some of the problems to the programming side (unless this is handled by the open-source software as well).