So Here is My data
ID C1 C2 C3
6 Digit 2 6,8,10,12
12 Digit 3 15
15 127 Digit 2 6,7,8,9,10,11,12,13
68 140,141 Digit 11 85,86,87,88,167,168,158,159
73 1 Digit 11 85,86,87,88,169,170
76 Digit 11 85,86,87,91,164,165,166,167,168
99 Digit 11 20,27,85,86,87
106 Digit 1 1,2
111 Digit 11 85,86,87,88
112 Digit 11 85,86,87,88
135 Digit 11 85,86,87
and my condition string is (2,6,15,37,42,52,62,65,79,85,94,100,104,107,113,124,131)
Now,I want to exclude row 3,4,5 if the values 127,140,141,1 are not in the list condition. I tried Not in , but no avail. I think I might be missing something basic, but just cant get it.
It's better not to store multiple values in a column if possible. Then it's easier to do queries like this.
You cannot use "IN" or "NOT IN" because they are looking for a list of separate items. But C3 is just one item that happens to have commas in it.
Try this:
SELECT * FROM
(SELECT ID, C1, C2, CONCAT('|',REPLACE(C3,',','|'),'|') as C3 FROM `table` WHERE `C3` ) as t1
WHERE t1.C3 NOT LIKE "|127|" AND t1.C3 NOT LIKE "|140|" AND t1.C3 NOT LIKE "|141|" AND t1.C3 NOT LIKE "|1|"
You could avoid the "|" and just concat "," to the start and end.
Or you could fix your database schema so that it actually acts like a Normalized Relational Database.
Every column that contains multiple values should be separated out into its own table.
There should be no column C3 in your table above. Instead, you should have a table, some_other_data:
At this point, I see that C3=6 is related to more than one record in the main table. Therefore, you actually need a third, linking table, in addition to some_other_data. See below.
`some_other_data`
id
6
8
10
12
15
`main_table_to_some_other_data_link`
some_other_data_id | main_table_id
6 6
8 6
10 6
12 6
15 12
6 15
etc. You can see that the linking table can contain duplicates of either value. But your other two tables would have completely unique ids.
I think you're trying to solve the wrong problem.
(I'm assuming you can change your table structure. If you can't someone else will need to address your question.)
The long lists of comma-separated data are a flag that they have a one-to-many relationship with ID.
For example, make the data in C3 its own table:
ID MainID C3
================
1 6 6
2 6 8
3 6 10
4 6 12
5 12 15
6 15 6
7 15 7
8 15 8
9 15 9
10 15 10
11 15 11
12 15 12
13 15 13
// and so forth //
So ID is the primary key of the new table, MainID is the foreign key that refers to the record in your primary table, and C3 is the data in C3.
Each separate value of C3 now has its own record.
Now, you're in a position to use something like
Select * from MainTable
Inner Join NewTable
On MainTable.ID = NewTable.MainID
Where NewTable.C3 Not In (2,6,15,37,42,52,62,65,79,85,94,100,104,107,113,124,131);
If you can, pulling out the one-to-many relationships into their own tables will make things easier for you.
Related
For example, let us consider this table:
In this image consists of rows of 8 where names like Mike,Glenn,Daryl,Shane and Patricia is included with their respective ages
Id
Name
Age
1
Mike
25
2
Glenn
19
3
Glenn
19
4
Daryl
56
5
Shane
30
6
Shane
30
7
Patricia
16
Now I want to insert the type of query that will show the names without repetitions like This, not like This
EDIT: I entered the data from first picture. The request is to list the names without duplicates, as shown in the second and third picture but I will not convert them to text.
DISTINCT specifies removal of duplicate rows from the result set.
SELECT DISTINCT Name
FROM tablename
see: use DISTINCT in SELECT
You can use GROUP BY to achieve it.
SELECT * FROM your_table
GROUP BY your_table.name
ORDER BY id
With the data you gave, the result from this query will be:
id
name
age
1
Mike
25
2
Glenn
19
4
Deryl
56
5
Shane
30
7
Patricia
16
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
First let me say that yes, this is a horrible way to have stored data, second, it isn't my fault :) I am trying to integrate with a 3rd party database to extract info which is stored in 3 tables, which really should have been in two AND stored where table 2 had a many to one relationship. Since that isn't the case, I have a puzzle to share.
Table one contains rows in which multiple values can be stored. Each row has codeid1-codeid20. These columns may contain a value, or a 0 (they are never null). They also have a corresponding codetype1-codetype20 which will be either 0 or 1.
If codetype1 is equal to 0, we go to table 2 and select description from the matching table1.codeid1=table2.id. If codetype1 equals 1, we now have to look at table3 and find where table1.codeid1=table3.id and then match table3.table2id=table2.id and return the description.
Here is the data structure:
table1
codeid1,codeid2,codeid3,...codeid20 ... codetype1,codetype2,codetype3,.....codetype20
18 13 1 33 0 0 1 1
13 21 45 0 0 1 0 0
table2
id, description
13 Item 13 Description
15 Item 15 Description
17 Item 17 Description
18 Item 18 Description
21 Item 21 Description
28 Item 28 Description
45 Item 45 Description
table3
id, table2id
1 15
33 17
21 28
The results I would be looking for would look like this:
rowid, description
1 Item 18 Description
1 Item 13 Description
1 Item 15 Description
1 Item 17 Description
2 Item 13 Description
2 Item 28 Description
2 Item 45 Description
I got started working with someone last night, but I had missed part of the complexity of my situation in not integrating table3. Like I said, fun puzzle... This gives me the relationship between the first 2 tables, but I am unsure how I can work in a 3rd table.
SELECT table1.rowid, table2.description
FROM table2
INNER JOIN table1
ON table2.id=table1.codeie1
OR table2.id=table1.codeie2
...
The database is a Faircom C-Tree DB over an ODBC connection, which is generally compatible with Mysql statements including UNION, WITH, INTERSECT, EXISTS, JOIN... There is no PIVOT function.
https://docs.faircom.com/doc/sqlref/sqlref.pdf
Perhaps it will work with or rather than in:
where exists (select 1
from table1 as t1
where t2.id = t1.codeid1 or
t2.id = t2.codeid2 or
. . .
);
I'm trying to normalize some data, and can't seem to come up with a solution. What I have is a table like this:
weight position1 position2 position3
1 10 20 30
2 25 35 45
3 17 05 22
and one like this:
location position
6 1
7 1
8 2
9 2
10 2
11 3
12 3
How do I normalize the above so that given a location and a weight, I can find the value for a given position?
I can use Perl, Python, Excel, MySQL or pretty much any tool on the block to do the actual reshuffling of the data; where I'm having a problem is in coming up with a reasonable schema.
The desired outcome here is something like
if location == 11 -> position is 3
therefore,
if weight == 2 -> the value is 45
The only thing to do is "unpivot" your first table to this:
weight position value
1 1 10
1 2 20
1 3 30
2 1 25
2 2 35
2 3 45
3 1 17
3 2 05
3 3 22
The first two columns should contain unique pairs of values. If you have other information that only depends on weight, you would need another table for that. Same for positions.
Converting to the new model
If you already have the tables, then you can create the first table (t1) with this statement:
create table t1_new
select weight, 1 as position, position1 as value
from t1
union all
select weight, 2 as position, position2 as value
from t1
union all
select weight, 3 as position, position3 as value
from t1
Then, after verification of the result, drop t1, and rename t1_new to t1.
Querying from the new model
To query from these tables the value for a given location and weight, you should use a join:
select value
from t1
inner join t2 on t2.weight = t1.weight
where t2.location = 11
and t1.position = 3
Table
id name(varhcar)
2 15
3 15,23
4 1315,424
5 1512,2323
6 23,15,345
7 253,234,15
I need to find out those values which contains 15 which mean i need 2,3,6,7 not 4,5.
Above is sample data, in real time it can be any number.
Can anyone please help me?
If your database is small, consider using find_in_set function:
select * from your_table
where find_in_set('15',name);
Consider change the model to master-detail table to increase the speed if you have a big table.
This is the kind of relational model you could adopt to make this an easy problem to solve:
TABLE: records
id
2
3
4
5
6
7
TABLE: values
record_id value
2 15
3 15
3 23
4 1315
4 424
5 1512
5 2323
6 23
6 15
6 345
7 253
7 234
7 15
Then you can query:
SELECT DISTINCT id FROM records
INNER JOIN values ON records.id = values.record_id AND values.value = 15
This is the only way you can take good advantage of MySQL's query optimizer.
Not that it's impossible to do what you're trying to do, but it kind of misses the point.
If you're already storing data in this format, you should write a one-time migration to transfer it to this "normalized" format in the programming language of your choice, using something like Java's split or PHP's explode.