MySQL string used in ORDER BY FIELD - mysql

I have an array of values stored in a single cell as a comma-separated string, thus:
"0,9,10,2,7,3,4,5,6,8,1,11,12"
I also have a table (table1) with a column (order) with these numbers in a different sequential order:
id|order
0 |5
1 |3
2 |4
3 |1
4 |2
etc
What I want to do is SELECT the "order" string from one table (table2) and use those values in an ORDER BY FIELD command when SELECTing from table1.
This should return row in this order: 3,4,1,2,0.
What I have so far is:
SELECT id
FROM table1
WHERE table1_id = 3746
ORDER BY FIELD(orderKey, (
SELECT `order` FROM table2
WHERE table2_id = 3746)
);
The problem seems to be that the SELECTorderFROM table2 is returned as a string which ORDER BY FIELD doesn't want to accept as input. It does SELECT the rows, but they are not in the specified order.
I have tried type-casting, but I may not have done this correctly. I also have sought an equivalent to a php explode function, to no avail.
MySQL version is 5.6.41
Any assistance is appreciated.

You can use FIND_IN_SET() in the ORDER BY clause:
select *
from table1
order by find_in_set(`order`, (select `order` from table2 where table2_id = 3746))
This will work if all the values in the column order of table1 exist in the string returned by the subquery as you mention in the question:
I also have a table (table1) with a column (order) with these
numbers in a different sequential order
.
See the demo.
Results:
| id | order |
| --- | ----- |
| 4 | 2 |
| 1 | 3 |
| 2 | 4 |
| 0 | 5 |
| 3 | 1 |

Related

MySQL table order by one column when other column has a particular value

I have two mysql tables record_items,property_values with the following structure.
table : property_values (column REC is foreign key to record_items)
id(PK)|REC(FK)| property | value|
1 | 1 | name | A |
2 | 1 | age | 10 |
3 | 2 | name | B |
4 | 3 | name | C |
5 | 3 | age | 9 |
table: record_items
id(PK) |col1|col2 |col3|
1 | v11| v12 | v13|
2 | v21| v22 | v23|
3 | v31| v32 | v33|
4 | v41| v42 | v43|
5 | v51| v52 | v53|
record_items table contains only basic information about the record, where as property_values table keeps record_item as a foreign key and each property and its value is saved in a separate row.
Now I want to get the record_items sorted based on a particular property, say by age.
My HQL query will be like
Select distinct rec from PropertyValues where property="age" order by value;
But this query will be skipping record 2 since it don't have an entry for property age.
I expect the result to have the records which contains age property in sort order appended by those which don't have age property at all. How can I query that?
Here is a raw MySQL query which should do the trick:
SELECT t1.*
FROM record_items t1
LEFT JOIN property_values t2
ON t1.id = t2.REC AND
t2.property = 'age'
ORDER BY CASE WHEN t2.value IS NULL THEN 1 ELSE 0 END, t2.Value
I notice that your Value column in property_values is mixing numeric and text data. This won't work well for sorting purposes.
Demo here

Retrieve rows in which a column doesn't contain a value

I have a MySQL table like below:
| ID | userIDs
---------------
| 1 | 4,3,5
| 2 | 2,3
| 3 | 1,2,3
I want to retrieve all the rows in which userIDs doesn't contain 1.
I tried
SELECT * FROM tablename WHERE 1 NOT IN (userIDs)
But it's not working.
Use FIND_IN_SET
SELECT * FROM tablename
WHERE find_in_set(1, userIDs) = 0
But actually you should rather change your table design. Never store multiple values in a single column!

MySQL Subselect issue

I have an issue with a mysql subselect.
**token table:**
id | token | articles
1 | 12345 | 7,6
2 | 45saf | 6,7,8
**items table:**
id | name | filename
6 | Some brilliant name | /test/something_useful.mp3
7 | homer simpson | /test/good-voice.mp3
**query:**
SELECT items.`filename`,items.`name` FROM rm_shop items WHERE items.`id` IN ( SELECT token.`articles` FROM rm_token token WHERE token.`token` = 'token')
I only get one of the two files (with the id 7 that is). What am I missing here?
For a column with concatenated data (like your "articles" column), you can not use MySQL IN() Function. Instead use the string function FIND_IN_SET() to query such values. In your case:
SELECT items.`filename`,items.`name` FROM rm_shop items
WHERE FIND_IN_SET(items.`id`,
(SELECT token.`articles` FROM rm_token token WHERE token.`token` = 'token')) > 0
A working sqlfiddle: http://sqlfiddle.com/#!2/796998/3/0

activerecord ruby row with max value in mysql table

I need to select from MySQL table table1 (it's shown below) all records with different 'foreign_row_id' values and group them by maximum datetime value. For example, from the table below I should select rows with id=2 and id=3. And after this I have to join the result with table with phrase_id's.
In my project I use only Ruby and ActiveRecord without Rails.
+----+---------------------+----------------+--------------+
| id | datetime | foreign_row_id | other_fields |
+----+---------------------+----------------+--------------+
| 1 | 2013-05-02 17:36:15 | 1 | 1 |
| 2 | 2013-05-02 17:36:53 | 1 | 1 |
| 3 | 2013-05-03 00:00:00 | 2 | 3 |
+----+---------------------+----------------+--------------+
Here my ruby code:
#result= Model1.joins(:foreign_row).
where(:user_id => user_id).
order(:datetime).
reverse_order.
select('table1.*, foreign_row.*').
maximum(:datetime, :group => :foreign_row_id).
And it gives me only one record, without grouping by id and joining: {"1":"2013-05-02T17:36:53+09:00"}.
What should I change in the my code to get all rows?
I solved this by parts, first I get a SQL sentence that would solve problem:
SELECT * FROM (SELECT * FROM `models` ORDER BY `datetime` desc) m GROUP BY `foreign_row_id`
And then I built that query with Arel:
model_table = Model1.arel_table
subquery = model_table.project(Arel.sql('*')).order('`datetime` desc').as('m')
query = model_table.project(Arel.sql('*')).from(subquery).group('`foreign_row_id`')
Finally you can run that query:
Model1.find_by_sql query.to_sql
I added some back ticks because fields I tested with were SQL reserved words, I think you can omit them.

Mysql select IN return null if id not exists

I have a table like this:
+----+---------+---------+
| Id | column1 | column2 |
+----+---------+---------+
| 1 | a | b |
| 2 | a | b |
+----+---------+---------+
and a query like this SELECT * FROM table WHERE id IN (1,2,3)
what query do I need to get a result like this(I need to get null values for nonexisten id's):
+----+---------+---------+
| Id | column1 | column2 |
+----+---------+---------+
| 1 | a | b |
| 2 | a | b |
| 3 | null | null |
+----+---------+---------+
EDIT
Thanks for the responses so far.
Is there a more 'dynamic way' to do this, the query above it's just an example.
In reality I need to check around 1000 id's!
You could use something like this:
SELECT ids.ID, your_table.column1, your_table.column2
FROM
(SELECT 1 as ID
UNION ALL SELECT 2
UNION ALL SELECT 3) ids left join your_table
on ids.ID = your_table.ID
First subquery returns each value you need in a different row. Then you can try to join each row with your_table. If you use a left join, all values from the first subquery are shown, and if there's a match with your_table, values from your_table are shown, otherwise you will get nulls.
That is not the way SQL works unfortunately. I would think it would be pretty trivial for your application to determine the differences between the id's it asked for and the id's returned.
So rather than hack or some weird query to mock up your result, why not have your application handle it?
I still can't understand though what the use case might be to where you would be querying rows on teh database by id's that may or may not exist.