Spliting MySql value with default function in mysql? - mysql

I Have a sitatation like the following:
In MySql Table Entries:
img_id name
1 aa.jpg
2 aab.mpeg
3 aabc.jpg
4 aabd.jpg
5 aabn.jpg
6 aabf.jpg
7 aadf.jpg
8 aacf.jpg
I want the count after splitting thew above values........
like
".jpg"=>7
".mpeg"=>1

SELECT RIGHT(Name, LOCATE('.', REVERSE(Name)) - 1) Format,
COUNT(*) TotalCOunt
FROM TableName
GROUP BY RIGHT(Name, LOCATE('.', REVERSE(Name)) - 1)
SQLFiddle Demo
Consider normalizing the table. In the long run, this will perform slow.

Related

What would be the SQL query/command to find length of numeric field from a table?

I want to know how we can find of length of Numeric field in sql. What will be the command / Query so that we can find length of perticular field in table.
E.g.:
For below table:
Column1 Column2
1 1111
2 11
3 44444
4 11
5 111
From above example I want to see Record/fields in column "column2" which has numeric length '2'.
What query should I execute to achieve this?
You can also use the POWER function and < and >= to maintain SARGability
WITH tbl (column1, column2) AS(
SELECT 1, 1111 UNION ALL
SELECT 2, 11 UNION ALL
SELECT 3, 44444 UNION ALL
SELECT 4, 11 UNION ALL
SELECT 5, 111
)
SELECT *
FROM tbl
WHERE
column2 < POWER(10, 2)
AND column2 >= POWER(10, 1)
Use LEN function
select *
from table
where len(column2) = 2
This will not work when you want to include data like '0.2' or similar values
You can't as stated here
Length and digits are both properties of a physical representation of a number in a specific base, i.e. a String.
So you have to convert numeric field to varchar/char first then find the length as follows:
SQL Server:
select *
from table
where len(CONVERT (varchar(10), colunm2 )) = 2
MySQL:
select *
from table
where length(convert(column2,char)) = 2

MySQL: Manipulate column data in a query with SELECT *

Is it possible to manipulate column data in a query where you do SELECT *?
table
id - delivery
1 - 0
2 - 0
3 - 12
Something like:
SELECT *, IF(delivery = '0', '9') FROM table
Or do you have to select the columns individually?
This would be a total mess for me since the actual table has like 40 columns.
EDIT: I didnt make myself clear what i wanted. The result should be:
id - delivery
1 - 9
2 - 9
3 - 12
Try this:
SELECT *, case delivery when '0' THEN '9' ELSE delivery END FROM table
Try this
,
Select
column1,
column2,
CASE WHEN delivery=0 THEN 9
ELSE delivery
END DELIVERY
from TABLE

MySQL multi-step GROUP BY without subquery

I'm working on improving some queries I inherited, and was curious if it was possible to do the following - given a table the_table that looks like this:
id uri
---+-------------------------
1 /foo/bar/x
1 /foo/bar/y
1 /foo/boo
2 /alpha/beta/carotine
2 /alpha/delic/ipa
3 /plastik/man/spastik
3 /plastik/man/krakpot
3 /plastik/man/helikopter
As an implicit intermediate step I'd like to group these by the 1st + 2nd tuple of uri. The results of that step would look like:
id base
---+---------------
1 /foo/bar
1 /foo/boo
2 /alpha/beta
2 /alpha/delic
3 /plastik/man
And the final result would reflect the number of unique tuple1 + tuple2 values, per unique id:
id cnt
---+-----
1 2
2 2
3 1
I can achieve these results, but not without doing a subquery (to get the results of the implicit step mentioned above), and then select/grouping out of that. Something like:
SELECT
id,
count(base) cnt
FROM (
SELECT
id,
substring_index(uri, '/', 3) AS base
FROM the_table
GROUP BY id, base
)
GROUP BY id;
My reason for wanting to avoid the subquery is that I'm working with a fairly large (20M rows) data set, and the subquery gets very expensive. Gut tells me it's not doable, but figured I'd ask SO...
There's no need for a subquery -- you can use count with distinct to achieve the same result:
SELECT
id,
count(distinct substring_index(uri, '/', 3)) AS base
FROM the_table
GROUP BY id
SQL Fiddle Demo
BTW -- this returns count of 1 for id 3 -- I assume that was a typo in your posting.

Oracle/MYSQL: Sort records from a select query on a column that contains alphanumeric values

I know that this question has been asked in various forms but my requirement happens to be a bit different.
Suppose I have a table that contains data as follows:
ID NAME VALUE
-----------------------------
1 ABC-2-2 X
2 PQRS-1-3 Y
3 ABC-3-2 Z
4 PQRS-1-4 A
5 PQRS-3-4 B
6 MNO-2-1 C
7 AAA-1 D
8 BBB-2 E
9 CCC-3 F
Now, the output that I'm expecting should look something like this:
ID NAME VALUE
-----------------------------
7 AAA-1 D
2 PQRS-1-3 Y
4 PQRS-1-4 A
8 BBB-2 E
6 MNO-2-1 C
1 ABC-2-2 X
9 CCC-3 F
3 ABC-3-2 Z
5 PQRS-3-4 B
Note that this is not a direct alpha-numeric sort. Instead, the value before the first "-" is ignored and the fields are sorted on what is after the first "-" in the name.
I'm not very familiar with PL/SQL and any kind of help on this would be appreciated.
Thanks.
PS: Note that this should work on both Oracle and MySQL.
For your example this would suffice (Oracle syntax):
ORDER BY SUBSTR(name,4)
If the number of characters before the first hyphen can vary, you can do this (again Oracle syntax):
ORDER BY SUBSTR(name,INSTR(name,'-')+1)
However that won't work if you have codes like:
AAA-10-1
AAA-8-1
AAA-9-1
and expect AAA-10-1 to appear after AAA-9-1. Then you will need to parse it further:
ORDER BY LPAD(SUBSTR(name,INSTR(name,'-')+1, INSTR(name,'-',1,2)-INSTR(name,'-')-1),10,'0'),
LPAD(SUBSTR(name,INSTR(name,'-',1,2)+1),10,'0')
(NB I have used LPAD(x,10,'0') to turn a value like '1' into '0000000001' and so on, rather than use TO_NUMBER since this could fail if there are any non-numerics in your data.)
Example:
with data as
(
select 'AAA-1' name from dual
union all
select 'PQR-1-4' name from dual
union all
select 'PQR-1-3' name from dual
union all
select 'AAA-10-10' name from dual
union all
select 'AAA-10-1' name from dual
union all
select 'AAA-9-10' name from dual
union all
select 'AAA-9-1' name from dual
)
select *
from data
ORDER BY LPAD(SUBSTR(name,INSTR(name,'-')+1, INSTR(name,'-',1,2)-INSTR(name,'-')-1),10,'0'),
LPAD(SUBSTR(name,INSTR(name,'-',1,2)+1),10,'0');
Output:
NAME
---------
PQR-1-3
PQR-1-4
AAA-9-1
AAA-9-10
AAA-10-1
AAA-10-10
AAA-1
And if AAA-1 should come first:
ORDER BY LPAD(SUBSTR(name,INSTR(name,'-')+1, INSTR(name||'-','-',1,2)-INSTR(name,'-')-1),10,'0'),
LPAD(SUBSTR(name,INSTR(name||'-','-',1,2)+1),10,'0') nulls first
Not sure about mysql syntax, but you can do this in oracle:
select * from <your_table>
order by substr(name, 5)
in mssql the syntax of finding your problem is :
select * from mytable order by substring(name,PATINDEX('%-%',name)+1,len(name)-PATINDEX('%-%',name))
SqlFiddle

MySQL How To Use Main Select Value As Subquery Argument?

I am trying to construct a query that is a bit more complicated than anything I've done in my limited experience with databases.
TABLE:
id - data - type - data3
1 - hello - 1 - 1
2 - goodbye - 1 - 1
3 - goodbye - 1 - 2
4 - goodbye - 2 - 1
5 - hello - 2 - 1
The goal is to do 4 things:
GROUP the results by "data", but only return one result/row of each
data type.
COUNT the total number of each "data GROUP and return this number.
Do this for both "type"=1 and "type"=2, though I only need each
"data" GROUP item once.
the ability to sort results based on each SELECT item.
So the final result returned should be (sorry to be confusing!):
data, COUNT(data["type"]=1), COUNT(data["type"]=2 AND data["data"] = data)
So, for the sample table above, desired results would be:
loop 1 - hello, 2, 1
loop 2 - goodbye, 3, 1
Then, ideally, I could sort results by any of these.
This is the query I was trying to construct before resorting to posting this, I don't think it's even close to being correct, but it may help illustrate what I'm trying to achieve a bit better:
SELECT
(
SELECT `clicks_network_subid_data`, COUNT(*)
FROM track_clicks
WHERE `clicks_campaign_id`='$id' AND `clicks_click_type` = '1'
) AS keywords,
(
SELECT COUNT(*)
FROM track_clicks
WHERE `clicks_campaign_id`='$id' AND `clicks_click_type` = '2' AND `clicks_network_subid_data` = keywords.clicks_network_subid_data
) AS offer_clicks
GROUP BY keywords.clicks_network_subid_data
ORDER BY keywords.COUNT(*) DESC
I also need to do a JOIN on another table to grab one more piece of data, but I think I can handle that once I get this part figured out.
You can use an IF-function for this
SELECT `clicks_network_subid_data`,
SUM(IF(clicks_click_type` == '1',1,0)) as keywords,
SUM(IF(clicks_click_type` == '2',1,0)) as offer_clicks,
FROM track_clicks
GROUP BY clicks_network_subid_data
ORDER BY clicks_network_subid_data DESC
You can do this using GROUP BY:
SELECT data, COUNT(*) AS cnt FROM `table` GROUP BY type ORDER BY COUNT(*)
Ordering might become a little slow, as this is a calculated field, but if you don't have a large result set then you are good to go.
First of all your question is bit not clear , However, check this query . what I suspect is that you need count results in columns (single ) instead of rows .
select * , count(type_one) as t1_count , count(type_two) as t2_count from (
select data,if(tmp.type=1,1,0) as type_one, if(tmp.type=2,1,0) as type_two from (
select 1 as id , 'hello' as data , 1 as type , 1 as data3 union
select 2 as id , 'goodbye' as data , 1 as type , 1 as data3 union
select 3 as id , 'goodbye' as data , 1 as type , 2 as data3 union
select 4 as id , 'goodbye' as data , 2 as type , 1 as data3 union
select 5 as id , 'hello' as data , 2 as type , 1 as data3
) tmp
) tmp2
group by tmp2.type_one ;
let me know if this works for you
cheers :)