Select by integer range in splitted string? - mysql

I'm new to MySQL and I currently have following problem:
I have a table "offers" where a user can place an offer to another user where he offers him ingame items. The items are placed into the datafield with the ItemID and ItemLevel separated by a ":" and the itemes by a ",".
Example: "0:346,2:638,1:646" = offers Item with ID 0 Level 346 and ID 2 Level 638 and ID 1 Level 646
Now I want to create a query with PHP to SELECT only offers with specific IDs and a range of Level.
Should I rebuild the whole thing and do it with 2 different tables "orders" and "order_data" or is it possible to make this filtering possible by a simple query?

You must normalize your data... As you say, you should distribute the orders data between multiple tables and columns.
However, there's a possible (and simple) solution for your request:
SELECT * FROM orders
WHERE 1=1
AND FIND_IN_SET('0:346', orderData)
;
FIND_IN_SET function returns the index of the searched string - if it exists on column - so it's usually used as a SELECT field in order to know string's index on comma separated string. But, as in this case, you can use it on WHERE clause in order to return only the records that contains the specific string.

Related

MYSQL select all record if contains specific number

I have a small problem, I have a table like this:
id|name|group|date_created
1|Volvo|1,3|06-04-2020 10:00:00
2|Audi|3|06-04-2020 10:00:00
etc....
Now I wish I could get all the records that have the value 1 inside the group column.
I tried LIKE "%1%", but I don't think it's a good query. Can you address me?
SELECT id FROM cars WHERE group LIKE '%1%'
The problem with your query is that it would wrongly match '1' against a list like '45,12,5' for example.
One method is to add commas on both ends before searching:
where concat(',', `group`, ',') like '%,1,%';
But in MySQL, it is much more convenient to use string function find_in_set(), whose purpose is just what you are looking for, ie search for a value in a comma-separated list:
select id from cars where find_in_set('1', `group`) > 0
Notes:
you should fix your data model, and have a separated table to store relationship between ids and groups, with each tuple on a separate row. Related reading: Is storing a delimited list in a database column really that bad?
group is a reserved word in MySQL, so not a good choice for a column name (you would need to surround it with backticks everytime you use it, which is error-prone)

How to add the numbers in comma separated string of numbers contained in a MySQL column?

I have a MySQL column which contains a string of scores separated by a semi-colon eg: "5;21;24;25;26;28;117".
This column was created not by design, but by collecting the values from multiple rows in a table using GROUP_CONCAT and GROUP BY. The original data arrived as a spreadsheet with multiple rows with the ID value.
I can use a select clause with REPLACE function to replace the ; with a +.
SELECT values, REPLACE(values,";","+") AS score FROM [table_name] WHERE 1
values score
5;21;24;25;26;28;117 5+21+24+25+26+28+117
However what I need is the sum of: 5+21+24+25+26+28+117 to get a total of 246.
Is there any way to do this in MySQL without using some other scripting language?
The SELECT clause shows me a string of numbers joined with the + symbol.
Am looking for a way to evaluate that string to give me the result: 246
UPDATE:
As I was framing my question, I did more research and came up with this link which solves my problem:
(https://dba.stackexchange.com/questions/120747/evaluate-a-string-value-as-a-computed-expression-in-an-sql-statement-sthg-like).
Am keeping this question and the link to the answer here in case it could help other people searching for the same.

MS Access IN operator not returning rows

Using an MS Access database (I know), the query below
SELECT * FROM PageImage WHERE (PageImage.Rooms) In ('1');
only returns rows when the 'PageImage.Rooms' column has a single value like 1
The actual data stored in the 'PageImage.Rooms' column is a comma separated list like 1,2,3 stored as a string, but no data is returned when this is the case.
From the above query & referring to the image below, only row 342 is returned, when I expect 341,342,343 to be returned
Given that PageImage.Rooms stores a genuine comma-delimited list as you specified in a comment (i.e. it is not an Access 2007+ multi-value field), you really have created a bit of a mess. A table containing such a column is for that reason completely un-normalized (not even in first normal form). Query and data consistency issues are to be expected.
The usual way to model a many-to-many relationship such as you have would be with a separate table. In this case, however, since the PageImage entity seems to have no data other than its Id, you could do it in the same table. Either way, whichever table models the relationship should have a separate row for each (PageImage.Id, Room) pair, and those pairs should be a composite key for the table.
With the structure you have now, the query you seem to want could be implemented like this:
SELECT * FROM PageImage
WHERE
PageImage.Rooms = '1'
OR PageImage.Rooms LIKE '*,1'
OR PageImage.Rooms LIKE '1,*'
OR PageImage.Rooms LIKE '*,1,*'
;
As Gord Thompson observed, that could be expressed more compactly, and perhaps more efficiently, as
SELECT * FROM PageImage
WHERE (',' & PageImage.Rooms & ',') LIKE '*,1,*'
;
As you can tell, it gets worse if you want to compare against multiple room numbers in the same query.
Bottom line: strings containing comma-delimited lists are just strings as far as the database is concerned.
I decided to scrap the multi-value string field & go down the correct route of creating a mappings table
The IN operation is the same action as performing an expanded OR statement where
SELECT * FROM PageImage WHERE (PageImage.Rooms) In ('1','2');
is the same as
SELECT * FROM PageImage WHERE PageImage.Rooms = '1' OR PageIMage.Rooms = '2';
Dealing with a partial match requires the LIKE keyword so SELECT * FROM PageImage WHERE PageImage.Rooms LIKE '*1*'; will return any field that has a one in any position within the field.

automatically Generate unique id for characters mysql

I want to create a mysql table with three columns id , name, name_id,
The thing that i want to acheive is whenever user enters a name into database
then system should generate a unique id for name automatically.
e.g.
name is JJ then name_id should be 1 and if name is DD then name_id should be 2
also if name JJ is repeated in database then name_id should be 1.
The number_id values should be assign according to name sorting
i.e A should get 1 and B should get 2.
How this can be achieved by sql script or triggers ?
What about the following?
INSERT INTO tbl (name,name_id)
SELECT newname, COALESCE((SELECT name_id FROM tbl WHERE name=newname ),
(SELECT max(name_id)+1 FROM tbl))
This is assuming that column id takes care of itself, i.e. is auto_incremented.
newname can of course also be a string constant which you will have to work in to your command.
The command above works best when used for indiviual inserts ("by a user"). If you want to carry out a bulk import then it can be quite costly since for each new value the table tbl will be scanned twice. For this case a different logic should be applied:
First find all name-name_id pairs by means of a grouped select and then INNER JOIN the results with the import list. For the remaining items (without existing name_ids) do the following: find out the highest #i=max(name_id) of all records and then import the sorted list with an autonumbering mechanism (#i:=#i+1) for name_id in place ...
create a sql function that returns the name
_id upon passing name as a parameter. one way would be to add all the characters but that wont do because different arrangement of same characters would give the same sum for different names.may be concatenating primary index at the end of sum would do the job. i think you can define a suitable logic in a sql function to achieve the results.

MS Access 2003 - ordering the string values for a listbox not alphabetical

Here is a silly question. Lets say I have a query that produces for a list box, and it produces values for three stores
Store A 18
Store B 32
Store C 54
Now if I ORDER BY in the sql statement the only thing it will do is descending or ascending alphabetically but I want a certain order (only because THEY WANT A CERTAIN ORDER) .....so is there a way for me to add something to the SQL to get
Store B
Store C
Store A
i.e. basically row by row what i want. thanks!
Add a numeric field, sequencer, to the table which contains the store names. Use the sequencer values to determine your sort order.
SELECT sequencer, store_name FROM YourTable ORDER BY sequencer;
In the list box, set the column width = 0 for the sequencer column.
Or simply, as #dscarr suggested, don't include sequencer in the SELECT field list, but just include it in the ORDER BY ...
SELECT store_name FROM YourTable ORDER BY sequencer;
You can do 1 of 2 things.
Either use a SWITCH stament, something like
SELECT Table1.Store,
Table1.Val,
Switch([Store]="StoreB",1,[Store]="StoreC",2,[Store]="StoreA",3) AS Expr1
FROM Table1
ORDER BY Switch([Store]="StoreB",1,[Store]="StoreC",2,[Store]="StoreA",3);
Or use a secondary order table, that stores the values of the store names, and an order by value.