Pick relevant value in a set of columns - mysql

It might be an easy question for DBA, but not for me.
I have a simplified Family table that looks like that: (part1 and part2 are ids)
famid
indiv1
indiv2
1
42
27
2
33
22
3
42
12
4
22
42
5
42
27
I can easily retrieve all families that match part1=X or part2=X
But the requested output format is to produce only the famid AND (part1 value or part2 value) BUT without the column that matches the value X.
For example, for a value of 42, the query should return:
[[1,27], [3,12], [4,22], [5,27]]
I would like to know if there is a 'simple' way to produce such a result with SQL query (or sequelize) only, but without a stored procedure.
Thx

Assuming you only have two columns to check and want to return the one that doesn't = X then you want to use a CASE statement to check if Indiv1 = 42. Then if it is return Indiv2 otherwise return Indiv1.
SELECT FamID
,CASE
WHEN Indiv1 = 42
THEN Indiv2
ELSE Indiv1
END AS Indiv
FROM Family
WHERE Indiv1 = 42
OR Indiv2 = 42
See my SQL Fiddle Demo

Related

Mysql Parsing logic on Multiple rows

I have parsing Queries with below references
link1 - SET and Select Query combine Run in a Single MySql Query to pass result in pentaho
link2
Input will be shown in below Col1 showing ,In #input in the above reference link i am considering only 1 records and applying parsing logic for each cell , but issue is with multiple rows (n rows) and combining result with parsing logic.
Col1
--------------
22:4,33:4
33:6,89:7,69:2,63:2
78:6
blank record
22:6,63:1
I want to create single Query for same as in reference link i asked for.
Expected Output
xyz count
------------
22 10
33 10
89 7
69 2
63 3
78 6
I tried solutions Passing values with this conditions
where condition pass 1 by 1 col1 in (my query)
MAX (col1)
group_concat
but i am not getting expected output to fit this all things in a single query.
I finally found solution for my question. and group_concat worked for this
#input= (select group_concat(Col1) from (select Col1 from table limit 10)s);
group_concat will merge all the rows of Col1 into comma seperated string
22:4,33:4,33:6,89:7,69:2,63:2,78:6,blank record,22:6,63:1
as we have now single string we can apply same logic as shown in link 1
we can replace blank record with REPLACE command and neglect it.
Output after using logic from link1 result
xyz count
------------
22 4
33 4
33 6
89 7
69 2
63 2
78 6
22 6
63 1
Just use Group by
select xyz,sum(count) from (select link1 output)s group by xyz;
will give you Final Output
xyz count
------------
22 10
33 10
89 7
69 2
63 3
78 6

MySQL WHERE RAND() Behaviour

Consider the following table foo:
a b v
0 9 1
10 19 2
20 29 3
30 39 4
40 49 5
50 59 6
60 69 7
70 79 8
80 89 9
90 100 10
a and b are the lower and upper boundaries of a certain value v. Example:
x = 79 => v = 8
This can be done with the following statement:
SELECT `v`
FROM `foo`
WHERE 79 BETWEEN `a` AND `b`
Which MySQL correctly returns:
v
8
For each number between 0 and 100 provided as input, MySQL will correctly return one, and only one number between 1 and 10.
Issue
However, if the input number is substituted with a random number generator, the behaviour is somewhat different:
SELECT `v`
FROM `foo`
WHERE ROUND(RAND()*100) BETWEEN `a` AND `b`
Instead of returning only one number, MySQL might return anything from empty result set up to 3 numbers!
Question 1
Is this the expected behaviour of the RAND() statement? What is the reasoning for this apparently weird behavior?
Question 2
Considering the intended purpose, is the statement correct? What would be the correct one? How to correct this behaviour?
An ansi-sql-friendly solution with a single query would look like
SELECT x.rnd, `v`
FROM yourTable y
INNER JOIN (SELECT RAND()*100 rnd) x
WHERE x.rnd BETWEEN y.`a` AND y.`b`;
it generates a random value just once and then is used in a joined query.
Demo: http://rextester.com/YOIW49684
The query and the base table are kindly borrowed from Tim Biegeleisen
If you want the same random value to be applied to every row of the query, then one option is to use a session variable:
SET #rnd = RAND()*100;
SELECT v
FROM foo
WHERE ROUND(#rnd) BETWEEN a AND b;
Demo

Sorting course_numbers like sorting using natsort

I have these sample course_numbers
cmsc 11
cmsc 2
cmsc 56
cmsc 21
cmsc 128
I use this query
SELECT * FROM subject ORDER BY LENGTH(`course_number`)
to natural sort the result
and it worked, but when i add these course_numbers
it 1
it 256
it 20
they kinda mess up.
What query should i use to order them like this
cmsc 2
cmsc 11
cmsc 21
cmsc 56
cmsc 128
it 1
it 11
it 20
it 100
it 256
I've searched and saw 'case' on their select statements but I do not know how to use them
You should consider splitting up the both parts of your course number, since "CMSC"/"IT" is one Part (even with variable length), and the real number is another part. If you store the number in a number column (int), you could easily correct them.
so it would be
SELECT concat(course_type, " ", course_subnumber) as course_number, ...
from subject
order by course_type, course_subnumber
As long as you have a bit luck, you could try with you structure the following:
SELECT * from subject
order by left(course_number, 2), length(course_number), course_number
then you get only in trouble if different course_types start with the same two letters.

Duplicating rows in one select MySql query

At first I would like greet all Users and apologize for my english :).
I'm new user on this forum.
I have a question about MySQL queries.
I have table Items with let say 2 columns for example itemsID and ItemsQty.
itemsID ItemsQty
11 2
12 3
13 3
15 5
16 1
I need select itemsID but duplicated as many times as indicated in column ItemsQty.
itemsID ItemsQty
11 2
11 2
12 3
12 3
12 3
13 3
13 3
13 3
15 5
15 5
15 5
15 5
15 5
16 1
I tried that query:
SELECT items.itemsID, items.itemsQty
FROM base.items
LEFT OUTER JOIN
(
SELECT items.itemsQty AS Qty FROM base.items
) AS Numbers ON items.itemsQty <=Numbers.Qty
ORDER BY items.itemsID;
but it doesn't work correctly.
Thanks in advance for help.
SQL answer - Option 1
You need another table called numbers with the numbers 1 up to the maximum for ItemsQuantity
Table: NUMBERS
1
2
3
4
5
......
max number for ItemsQuantity
Then the following SELECT statement will work
SELECT ItemsID, ItemsQty
FROM originaltable
JOIN numbers
ON originaltable.ItemsQty >= numbers.number
ORDER BY ItemsID, number
See this fiddle -> you should always set-up a fiddle like this when you can - it makes everyone's life easier!!!
code answer - option 2
MySQL probably won't do what you want 'cleanly' without a second table (although some clever person might know how)
What is wrong with doing it with script?
Just run a SELECT itemsID, ItemsQty FROM table
Then when looping through the result just do (pseudo code as no language specified)
newArray = array(); // new array
While Rows Returned from database{ //loop all rows returned
loop number of times in column 'ItemsQty'{
newArray -> add 'ItemsID'
}
}//end of while loop
This will give you a new array
0 => 11
1 => 11
2 => 12
3 => 12
4 => 12
5 => 13
etc.
Select DISTINCT items.itemsID, items.itemsQty From base.items left outer join (select items.itemsQty as Qty from base.items) As Numbers On items.itemsQty <=Numbers.Qty
order by items.itemsID;
Use DISTINCT to remove duplicates. Read more here - http://dev.mysql.com/doc/refman/5.0/en/select.html
It seems like I understood what you asked differently than everyone else so I hope I answer you question. What I would basically do is -
create a new table for those changes.
Create a mysql procedure which given a line in the original table add new lines to the new table - http://dev.mysql.com/doc/refman/5.6/en/loop.html
Run this procedure for each line in the original table.
try this to get distinct values from both columns
SELECT DISTINCT itemsID FROM items
UNION
SELECT DISTINCT itemsQty FROM items

What would be the best practice to store multiple 2 digit dataset in MySql server

Let say i want to store several dataset ie
78 94 33 22 14 55 18 10 11
44 59 69 79 39 49 29 19 39
And later on i would like to be able run queries that will determine the frequency of certain number. What would be the best way to this? What would be table structure to make a fast query.
Please be specific as you can be.
To get the counts, you can run a query such as:
SELECT value, COUNT(*) from table_of_values GROUP BY value
Placing an index on the single integer value column is pretty much all you can do to speed that up.
You could of course also just keep a table with every two-digit value and a count. You will have to pre-fill the table with zero counts for every value.
Then increment the count instead of inserting:
UPDATE table_of_values SET count = count + 1 WHERE value = (whatever)