Mysql - GROUP_CONCAT - Control order of other / merged columns - mysql

Given a table like this:
id number anotherNumber
1 1 10
2 1 20
3 2 20
4 2 10
5 3 10
If I run the query:
Select *, GROUP_CONCAT(number)
FROM docs
GROUP BY number
I will get:
id number anotherNumber GROUP_CONCAT(number)
1 1 10 1,1
3 2 20 2,2
5 3 10 3
see sql fiddle
However I want to get:
id number anotherNumber GROUP_CONCAT(number)
1 1 20 1,1
3 2 20 2,2
5 3 10 3
Basically I want the numbers in the anotherNumber column to be sorted in DSEC order - it should always be the highest one.
I know you can put an ORDER BYin the GROUP_CONCAT but this will only affect the concatenated values, not the "merged ones". So is there a simple way?

You could use:
Select MIN(id) AS ID, number, MAX(anotherNumber) AS anotherNumber,
GROUP_CONCAT(number)
FROM docs
GROUP BY number;
SQLFiddle Demo
You should always wrap columns that are not specified in GROUP BY with aggregate function(unless they are functionally dependent on GROUP BY columns and your RDBMS supports ANSI-99 Optional feature T301, Functional dependencies)

The following code is the easy way to get the desired result:
SELECT id, number, MAX(anotherNumber) AS anotherNumber, GROUP_CONCAT(number)
FROM docs
GROUP BY number;
I have also attached my SQLFiddle.
You can check it. Good Luck!

Related

how to sum of a column with different values

I have a MySQL table which contains val_type column which have 3 type of values
id val_type company
1 rib 1
2 mod 2
3 rib 2
4 rib 3
5 mod 1
6 trop 1
$res= SELECT SUM(val_type) from tabl_name GROUP BY company;
with above query I get sum of all types in one
Result Required : Rib=3, mod=2 and trop=1
I want to get sum of all three types with one MySQL query. like how many rib,mod and trop.
Thanks
It sounds like you want to count all three types. You only need a basic GROUP BY query:
SELECT
val_type,
COUNT(*) AS cnt
FROM tabl_name
GROUP BY
val_type;

MySQL where condition when intersecting 2 values (comma delimited)

I have table like this:
id products
------ ----------
5 1,2,3
6 2,4,5
9 1,4,7
17 4,6,7
18 1,6,8
19 2,3,6
I have to select only that rows, which row's products column contains one of (2,3) values.
In this case query must return:
id products
------ ----------
5 1,2,3
6 2,4,5
19 2,3,6
But I don't understand how to make construction of this query.
Any ideas?
Thanks in advance.
SELECT id,products
FROM yourTable
WHERE FIND_IN_SET('2',products)>0
OR FIND_IN_SET('3',products)>0
sqlFiddle
Would you mind to try this one please?
select * from TABLE_NAME where products regexp "(^|,)[23](,|$)";
Its doing either two or three at the begining, or at end. Or in between the commas.
Never, never, never store multiple values in one column.
Like you see now this will only give you headaches. Normalize your table. Then you can select normally.
Your table should look like this
id product
-- -------
5 1
5 2
5 3
6 2
6 4
6 5
...
With that table structure your select would be
select id
from your_normalized_table
where product in (2,3)
group by id
having count(distinct product) = 2
That query can make use of indexes and is really fast.

What is the difference between MySQL LIMIT range of 0,500 and 1, 500?

If I want in MySQL rows 1 through 500, should I use LIMIT 0, 500 or LIMIT, 1, 500? What is the difference? Thanks!
The first one starts from the first record of the whole result, while the second one starts on the second record of the result.
Consider the following records
ID
1 -- index of the first record is zero.
2
3
4
5
6
if you execute
LIMIT 0, 3
-- the result will be ID: 1,2,3
LIMIT 1, 3
-- the result will be ID: 2,3,4
SQLFiddle Demo
OTHER(s)
Limit - MySQL Command (for more info)
In MySQL, the meaning of LIMIT n1, n2 is :
n1 : starting index
n2 : number of record/data you want to show
For example :
ID
-------------------------
1 ------------ > index 0
2
3
4
5
6
7
8
9
10 ------------ > index 9
Now if you write query like
SELECT * from tbl_name LIMIT 0,5
Output :
1
2
3
4
5
And if you write query like
SELECT * from tbl_name LIMIT 2,7
Output :
3
4
5
6
7
8
9
#JohnWoo That's not correct. The order of rows from a SELECT statement, with no ORDER BY clause, is unspecified. Therefore even though by visually looking at the output order of such a query it may seem to be in a specific order, that order is not guaranteed and therefore not reliable. If you require a result set to be ordered in a certain way you must use an ORDER BY clause.
ID
1
2
3
4
5 ------------ > index 0
6
7
8
9 ------------ > after 5 index add 4 value
10
If you want data from 5 to 9 so query should be
SELECT * from table_name LIMIT 5,4

SQL - counting rows with specific value

I have a table that looks somewhat like this:
id value
1 0
1 1
1 2
1 0
1 1
2 2
2 1
2 1
2 0
3 0
3 2
3 0
Now for each id, I want to count the number of occurences of 0 and 1 and the number of occurences for that ID (the value can be any integer), so the end result should look something like this:
id n0 n1 total
1 2 2 5
2 1 2 4
3 2 0 3
I managed to get the first and last row with this statement:
SELECT id, COUNT(*) FROM mytable GROUP BY id;
But I'm sort of lost from here. Any pointers on how to achieve this without a huge statement?
With MySQL, you can use SUM(condition):
SELECT id, SUM(value=0) AS n0, SUM(value=1) AS n1, COUNT(*) AS total
FROM mytable
GROUP BY id
See it on sqlfiddle.
As #Zane commented above, the typical method is to use CASE expressions to perform the pivot.
SQL Server now has a PIVOT operator that you might see. DECODE() and IIF() were older approaches on Oracle and Access that you might still find lying around.

sql to select top 10 records

I have the following table (points):
recno uid uname points
============================
1 a abc 10
2 b bac 8
3 c cvb 12
4 d aty 13
5 f cyu 9
-------------------------
--------------------------
What I need is to show only the top ten records with by points (desc) and five records on each page. I have following the SQL statement:
select * from points where uid in(a,c) order by uid LIMIT 1, 5
Thanks
for the first page:
SELECT * FROM points p ORDER BY points DESC LIMIT 0, 5
for the second page:
SELECT * FROM points p ORDER BY points DESC LIMIT 5, 5
You can't execute an SQL query to return a set number of pages, you'll have to implement some kind of pagination module or whatever equivalent there is for the scenario you're in and fetch LIMIT 0, 5 for one then LIMIT 5, 5 for the other.
With such few records it wouldn't be an issue but in a production scale environment selected all records then breaking those results down into pages would be a lot of unnecessary overhead, it's good practice to only select the data you need.