I have a table, named group, in mysql. One of its field is member_ids where values are like (2,3,4,5).
I want to use 2,4,5 excluding 3 in one place and 3 excluding others in another.
I am using mysql as a database for PHP. Any idea how to do it with mysql query or php code?
member_ids: (2,3,4), (2,3,4,5), (1,3,5,7) ...
There are multiple values in single cell.
Now I want to use all values of 2nd cell except 3 i.e. (2,4,5) to find email_id from another table member.
I can only use '3' in the query, not the rest i.e. (2,4,5).
I need to find email id of 'id'= 2, 4 and 5 from member table.
To get all member_ids whose value is excluding 3 , you can write
select member_ids from group where member_ids != 3;
to get all member_ids whose value is 3 excluding others, you can write
select member_ids from group where member_ids = 3;
You can use FIND_IN_SET() like this:
SELECT g.member_ids
FROM group g
WHERE FIND_IN_SET('2', g.member_ids) > 0
OR FIND_IN_SET('4', g.member_ids) > 0
OR FIND_IN_SET('5', g.member_ids) > 0
Related
Is it possible to sort in MySQL by "order by" using a predefined set of column values (ID) like order by (ID=1,5,4,3) so I would get records 1, 5, 4, 3 in that order out?
UPDATE: Why I need this...
I want my records to change sort randomly every 5 minutes. I have a cron task to update the table to put different, random sort order in it.
There is just one problem! PAGINATION.
I will have visitors who come to my page, and I will give them the first 20 results. They will wait 6 minutes, go to page 2 and have the wrong results as the sort order has already changed.
So I thought that if I put all the IDs into a session on page 2, we get the correct records even if the sorting had already changed.
Is there any other better way to do this?
You can use ORDER BY and FIELD function.
See http://lists.mysql.com/mysql/209784
SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)
It uses Field() function, Which "Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found" according to the documentation. So actually you sort the result set by the return value of this function which is the index of the field value in the given set.
You should be able to use CASE for this:
ORDER BY CASE id
WHEN 1 THEN 1
WHEN 5 THEN 2
WHEN 4 THEN 3
WHEN 3 THEN 4
ELSE 5
END
On the official documentation for mysql about ORDER BY, someone has posted that you can use FIELD for this matter, like this:
SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)
This is untested code that in theory should work.
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC
If I had 10 registries for example, this way the ID 1, 5, 4 and 3 will appears first, the others registries will appears next.
Normal exibition
1
2
3
4
5
6
7
8
9
10
With this way
8
5
4
3
1
2
6
7
9
10
There's another way to solve this. Add a separate table, something like this:
CREATE TABLE `new_order` (
`my_order` BIGINT(20) UNSIGNED NOT NULL,
`my_number` BIGINT(20) NOT NULL,
PRIMARY KEY (`my_order`),
UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;
This table will now be used to define your own order mechanism.
Add your values in there:
my_order | my_number
---------+----------
1 | 1
2 | 5
3 | 4
4 | 3
...and then modify your SQL statement while joining this new table.
SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order;
This solution is slightly more complex than other solutions, but using this you don't have to change your SELECT-statement whenever your order criteriums change - just change the data in the order table.
If you need to order a single id first in the result, use the id.
select id,name
from products
order by case when id=5 then -1 else id end
If you need to start with a sequence of multiple ids, specify a collection, similar to what you would use with an IN statement.
select id,name
from products
order by case when id in (30,20,10) then -1 else id end,id
If you want to order a single id last in the result, use the order by the case. (Eg: you want "other" option in last and all city list show in alphabetical order.)
select id,city
from city
order by case
when id = 2 then city else -1
end, city ASC
If i had 5 city for example, i want to show the city in alphabetical order with "other" option display last in the dropdown then we can use this query.
see example other are showing in my table at second id(id:2) so i am using "when id = 2" in above query.
record in DB table:
Bangalore - id:1
Other - id:2
Mumbai - id:3
Pune - id:4
Ambala - id:5
my output:
Ambala
Bangalore
Mumbai
Pune
Other
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC
I have this table with one column
A:
16654,16661
16661,16654
16670,16717
16717,16670
I want to have this: (ignore duplicate values without consider of their position)
16661,16654
16670,16717
is there any math function that operate between two number and have unique result?
actually i have this table ( name:class)
id second_code have_second_code
1 0 no
2 3 yes
3 2 yes
4 5 yes
5 4 yes
when "have_second_code" is "yes"
column second_code have a value!
id is primary
second code is from id column and there is a binary relation between them. now i need this output 2,3 and 4,5
SELECT rowone, rowtwo, rowonemillion FROM yourtable GROUP BY(nodupecolumn)
I suppose, that your query that produces this one-column-multiple-values-table uses GROUP_CONCAT(). In this case you need to do it like this:
SELECT DISTINCT GROUP_CONCAT(DISTINCT whatever_column ORDER BY whatever_column) FROM ...
Use the DISTINCT keyword two times. In GROUP_CONCAT(), so that duplicates are removed from the comma separated values, and one time outside of GROUP_CONCAT(), so that duplicate rows are removed. The ORDER BY in GROUP_CONCAT() is important, otherwise the outer DISTINCT won't detect duplicates. Also note, that (outer) DISTINCT works on the whole row, not just one column.
In my mysql table one of the field has values like (1|2|3) stored in it.
id Skills
---- --------
1 1|2|3|5
2 2|4|5
3 4|6|3
4 5|2|3|1
I want to search and list the id's based on the skills matched. If i want to list the id's of the skill which contains 3, i have to list the ids 1,3,4. Like if i want to list the id's of the skill which contains 1,5 (either 1 nor 5 or both)(like mulitple values 1,4,3) then i want to list 1,2,4(i want to list 2 also). Any help could be greatly appreciated.
Thanks in advance.
Use FIND_IN_SET
select id
from your_table
where find_in_set('3', replace(skills, '|',',') > 0
select id
from your_table
where find_in_set('3', replace(skills, '|',',')) > 0
or find_in_set('5', replace(skills, '|',',')) > 0
But you should actually change your DB structure. Always store single values in a column to avoid such problems!
This may help:
SELECT * FROM YOUR_TABLE
WHERE Skills REGEXP '[[:<:]]1[[:>:]]' = 1
OR Skills REGEXP '[[:<:]]5[[:>:]]' = 1
I want to ignore the duplicates in my database when I will set my "LIMIT 0, 50", then "LIMIT 50, 50" then LIMIT..... I will need to scan the duplicates on only 1 column of my table, not all the columns at once. I can't merge the duplicates because they are different in a way : these duplicates have different prices.
more precisely, I will need to show a list of these items, but to show their different prices at their right.
I need a precise number (50) per pages, so I cant load less then go to the next page. I could therefore load more from the beginning (changing the max and previous offsets if i'm on a far page) in a way that if i ignore the duplicates, I will got exactly 50 per pages and I will get the good number of pages shown at the end.
I'm a bit beginner with PHP and I have no idea about how to do that. Maybe pre-scan all the table and then start writing my code, by being flexible with my scan's variables of LIMIT and everything ? what functions I need ? how ?
Else, do something pre-programmed or a function of php that I don't know it exists can solve this problem ? Or I really need to get an headhache xD
I am not entirely certain of what you are asking, but I think you might want to do a aggregate statement along these lines:
select
itemID,
group_concat(itemPrice)
from
yourTable
group by
itemID
limit 50
This will bring back a list of 50 items and a second column where all the prices are grouped together. Then in your PHP code, you can either explode() that second column keep it as is.
Edit: If you select every field, you can't then use an aggregate function. If you want to select other columns that won't be different, add them to both the select and the group by sections like this:
select
itemID,
itemName,
itemSomething,
itemSomethingElse,
group_concat(itemPrice)
from
yourTable
group by
itemID,
itemName,
itemSomething,
itemSomethingElse
limit 50
Probably you can group by item, and use GROUP_CONCAT to show different prices list? In this way you can still use LIMIT 50. If the price column is numeric, cast it to VCHAR.
I admit I borrowed the group_concat() function from the other answers :)
After reading this paragraph from the docs:
The default behavior for UNION is that duplicate rows are removed from the result.
The optional DISTINCT keyword has no effect other than the default because it also
specifies duplicate-row removal. With the optional ALL keyword, duplicate-row removal
does not occur and the result includes all matching rows from all the SELECT statements.
Assume the following table (testdb.test):
ID Name Price
1 Item-A 10
2 Item-A 15
3 Item-A 9.5
4 Item-B 5
5 Item-B 4
6 Item-B 4.5
7 Item-C 50
8 Item-C 55
9 Item-C 40
You can page this table rows (9 rows) or groups (3 groups, based on the item's name).
If you would like to page your items based on the item groups, this should help:
SELECT
name, group_concat(price)
FROM
testdb.test
GROUP BY name
LIMIT 1 , 3
UNION SELECT
name, group_concat(price)
FROM
testdb.test
GROUP BY name
LIMIT 0 , 3; -- Constant 0, range is the same as the first limit's
If you would like to page your items based on all the items (I don't think that's what you were asking for, but just in case it helps someone else), this should help:
SELECT
name, price
FROM
testdb.test
LIMIT 1 , 5
UNION SELECT
name, price
FROM
testdb.test
LIMIT 0 , 5; -- Constant 0, range is the same as the first limit's
A very important thing to note is how you'll have to modify the limits. The first limit is your key, you can start from any limit you'd like as long as it's <= count(*) but you will have to have the same range as the second limit (i.e 3 in the first example and 5 in the second example). And the second limit will always start from 0 as shown.
I enjoyed working on this, hope this helps.
for example i have a table like this :
name rating
matei 124
andrei 20
serj 25
john 190
mike 96
andy 245
tom 73
i need to output something like this(order by rating):
john's position is 2; or, tom's position is 5; (i don't need to get all result , just one )
How can I achieve this?
Thanks in advance
Generally order of rows in a query result is not guaranteed by MySQL unless ordering is explicitly specified with ORDER BY clause. If you have some separate ordering column, you may use query like the following:
SELECT count(1) as position
FROM table
WHERE order_column <= {john's order_column value};
If you don't have ordering column, I'd recommend you to define first, what does "john's position" and "tom's position" mean.
UPDATE:
AFAIU, you want to get position in list sorted by rating (sorry, I initially did not get it). So, rating would be your order_column. In this case, you should decide, how do you calculate position, if two guys have equal rating (who's position is higher?).
So, the query may look in the following way:
SELECT count(1) as position
FROM table
WHERE
rating > (SELECT rating FROM table WHERE id={user's ID});
SELECT COUNT(*) + 1
FROM users
WHERE (rating, name) <
(
SELECT rating, name
FROM users
WHERE name = 'john'
)
Note that if you will have duplicates on both name and rating, this query will assign the same rating to both of them.
Tables are more formally known as relations in database literature - they are not guaranteed to be ordered (they are sets of "tuples"), so your question doesn't make sense. If you need to rely on an order/position, you need to define an additional column (like an auto-incrementing ID column) to capture and store that info.
Is this any help > http://craftycodeblog.com/2010/09/13/rownum-simulation-with-mysql/ ?
Would offset not work like so?
SELECT * FROM Table ORDER BY rating DESC LIMIT 1,6
This would return 1 row that has been off setted by 6 rows ? or am I mistaken, the syntax would be
SELECT * FROM Table ORDER BY rating DESC LIMIT 1 , {{POS}}