mysql rename results? - mysql

I have this function
SELECT LEFT( eventName, INSTR( CONCAT( eventName, ':' ) , ':' ) ) AS prefix, COUNT( * )
FROM trackingevent
GROUP BY LEFT( eventName, INSTR( CONCAT( eventName, ':' ) , ':' ) )
UNION SELECT homeupload, COUNT( * )
FROM link
GROUP BY homeupload
UNION
SELECT mediaType, COUNT( * )
FROM link
GROUP BY mediaType
UNION
SELECT emailSub, COUNT(*) FROM link WHERE emailSub='1' GROUP BY emailSub
and it generates something like
prefix COUNT(*)
CONTEST_ENTRY: 4
EMAIL_SHARE 77
FLICKR_SHARE 9
SHARE_FACEBOOK 105
SHARE_STATION_LOGIN 223
TWEET_SHARE 18
0 320
1 1
image 320
video 1
1 195
I want to rename the 0,1 and the other 1 to something else. Maybe homeupload, onsite, or something.
The first 0 and 1 are UNION SELECT homeupload, COUNT( * )
FROM link
GROUP BY homeupload
As there are two values
The second 1 is UNION
SELECT emailSub, COUNT(*) FROM link WHERE emailSub='1' GROUP BY emailSub
How can I rename the results?

in short, using IF
...
UNION
SELECT IF(homeupload = 0,
"someStringDescribingStatus0",
"someStringDescribingStatus1") as homeUploadStatus,
count(*)
FROM ...

Related

UPDATE statement using the same table in subquery

SELECT
vl1.phone_number,
vl1.first_name,
CONCAT(
SUBSTRING(
(
SELECT
vl2.phone_number
FROM
list as vl2
WHERE
vl2.phone_number LIKE CONCAT( SUBSTRING( vl1.phone_number FROM 1 FOR 3 ), "%" )
ORDER BY
RAND( )
LIMIT 1
)
FROM
1 FOR 6
),
FLOOR( RAND( ) * ( 8999 ) ) + 1000
) AS autogenNumber
FROM
list as vl1
LIMIT 1
The results I get are
phone_number | firstname | autogenNumber
The autogenNumber is generated by first searching for other numbers that share the first three digits. Then 6 digits from that number are picked and another 4 random digits are subsituted to the end.
The above sql query generates the autogen number exactly as I need it.
However, now the issue arises when I want to update the column security_phrase in this list using the similar query below.
UPDATE list as vl1
SET vl1.security_phrase = (
CONCAT(
SUBSTRING(
(
SELECT
vl2.phone_number
FROM
list AS vl2
WHERE
vl2.phone_number LIKE CONCAT( SUBSTRING(phone_number FROM 1 FOR 3 ), "%" )
ORDER BY
RAND( )
LIMIT 1
)
FROM
1 FOR 6
),
FLOOR( RAND( ) * ( 8999 ) ) + 1000
)
)
LIMIT 10
Gives me an error:
1093 - Table 'vl1' is specified twice, both as a target for 'UPDATE'
and as a separate source for data
I have also tried
UPDATE list AS vl1
JOIN list AS vl2
SET vl1.security_phrase = (
CONCAT( SUBSTRING( vl2.phone_number FROM 1 FOR 6 ), FLOOR( RAND( ) * ( 8999 ) ) + 1000 )
)
WHERE
vl2.phone_number LIKE CONCAT( SUBSTRING( vl1.phone_number FROM 1 FOR 3 ), "%" )
Not working and does not give the intended results...
Any help
MySQL does not allow referencing the table being updated again in another subquery, unless it is inside the FROM clause (Derived Table).
Now, in your particular case, we will need to put the complete SELECT query block as a Derived Table. As discussed in chat, lead_id is your Primary Key, so we will join back using the PK to update the rows accordingly.
UPDATE list AS t1
JOIN
(
SELECT
vl1.lead_id,
CONCAT(
SUBSTRING(
(
SELECT
vl2.phone_number
FROM
list as vl2
WHERE
vl2.phone_number LIKE CONCAT( SUBSTRING( vl1.phone_number FROM 1 FOR 3 ), "%" )
ORDER BY
RAND( )
LIMIT 1
)
FROM
1 FOR 6
),
FLOOR( RAND( ) * ( 8999 ) ) + 1000
) AS autogenNumber
FROM
list as vl1
) AS dt
ON dt.lead_id = t1.lead_id
SET t1.security_phrase = dt.autogenNumber

How to select only particular word start with # from sentence mysql query

let's explain briefly
this is very new topic, I want to fetch only particular word start with # from sentence for example
i have sentence like
Hi Majjx Uxud Xhhxhd Hx Dhx #hdhd Jdhhdhshhfd Hxhhd #bhd Hxhd Hxhhd Dhhdh www.myinnos.in Hdhd Xfhhxhd Xhhdh Xhx 9560233669 ndhdh Hxhhdh Dhh
from above sentence I have to fetch #hdhd
got a solution for my question, now I want to count and show the repeated words as count
select val from(
select (substring_index(substring_index(a, ' ', n.n), ' ', -1)) val
from (select id, message as a from filmbooknewsfeed) t
cross join(
select a.n + b.n * 10 + 1 n
from
(select 0 as n union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) a,
(select 0 as n union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) b
order by n
) n
where n.n <= 1 + (length(t.a) - length(replace(t.a, ' ', '')))
order by val asc
)x where val like '#%'
As I said, you need to convert the sentence into rows. Just in case, if in sentence you have more than 1 words start with #.
select val from(
select (substring_index(substring_index(a, ' ', n.n), ' ', -1)) val
from (
select 'Hi Majjx Uxud Xhhxhd Hx Dhx #hdhd Jdhhdhshhfd Hxhhd #bhd Hxhd Hxhhd Dhhdh www.myinnos.in Hdhd Xfhhxhd Xhhdh Xhx 9560233669 ndhdh Hxhhdh Dhh' as a
) t
cross join(
select a.n + b.n * 10 + 1 n
from
(select 0 as n union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) a,
(select 0 as n union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) b
order by n
) n
where n.n <= 1 + (length(t.a) - length(replace(t.a, ' ', '')))
order by val asc
)x where val like '#%'
Will give you #hdhd. even if you has more than 1 # in the sentence. This would give you correct result.
edit
If you want to group by result and sort by most occurence words like twitter tranding topic, modify your query like this (as query on the question)
select val,count(val) as cnt from(
select (substring_index(substring_index(a, ' ', n.n), ' ', -1)) val
from (select id, message as a from filmbooknewsfeed) t
cross join(
select a.n + b.n * 10 + 1 n
from
(select 0 as n union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) a,
(select 0 as n union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9
) b
order by n
) n
where n.n <= 1 + (length(t.a) - length(replace(t.a, ' ', '')))
order by val asc
)x where val like '#%'
group by val
order by cnt desc
You can do this using substring_index():
select substring_index(substring_index(substring_index(sentence, '#', 2), '#', -1), ' ', 1)

Find elements in a set that are not in another set using native MySQL functions

I have two variables having comma separated IDs.
SET #Set1 = '1,2,3,4';
SET #Set2 = '3,2,5,6';
I want to get all elements in Set1 that are not in Set2 using just MySQL functions. In the above case,
the answer is: '1,4'.
Please note that I want to use only native MySQL functions.
the easiest way would be to normalize your set you want to find the results in and then use FIND_IN_SET() on the second set like so
SET #Set1 = '1,2,3,4';
SET #Set2 = '3,2,5,6';
SELECT col
FROM
( SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(#Set1, ',', n.digit+1), ',', -1) col
FROM (SELECT #set1) temp
JOIN(SELECT 0 digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) n
ON LENGTH(REPLACE(#Set1, ',' , '')) <= LENGTH(#Set1)-n.digit
ORDER BY n.digit
) t
WHERE NOT FIND_IN_SET(col, #set2);
if you want to capture as many comma separated digits as you can then just do this
SELECT col
FROM
( SELECT
SUBSTRING_INDEX(SUBSTRING_INDEX(#Set1, ',', n.digit+1), ',', -1) col
FROM (SELECT #set1) temp
JOIN
( SELECT
SEQ.SeqValue as digit
FROM
( SELECT (HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue
FROM(SELECT 0 SeqValue UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) ONES
CROSS JOIN(SELECT 0 SeqValue UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30 UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60 UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90) TENS
CROSS JOIN(SELECT 0 SeqValue UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300 UNION ALL SELECT 400 UNION ALL SELECT 500 UNION ALL SELECT 600 UNION ALL SELECT 700 UNION ALL SELECT 800 UNION ALL SELECT 900) HUNDREDS
) SEQ
) n
ON LENGTH(REPLACE(#Set1, ',' , '')) <= LENGTH(#Set1)-n.digit
ORDER BY n.digit
) t
WHERE NOT FIND_IN_SET(col, #set2);
which will return up to 1000 items in a single comma separated list

Split values then resolve the values to a name

I need to be able to do something with my column (below) that can contain multiple values. The 'HearAboutEvent' column has multiple values separated by a comma. Each one of these values corresponds to an entry in another table. So the value of 11273 will equal facebook, 11274 will mean radio, and 11275 will mean commercial.
The data I am working with looks like this:
weather ID MemberID SubscriptionID DateEntered ParticipatedBefore ParticipatedBeforeCities WeatherDependent NonRefundable TShirtSize HearAboutEvent
Yes 24 18 1 2013-12-19 0 NULL 10950 10952 10957 11273, 11274, 11275
I am able to do the proper join to resolve the value of 'weather', note it is the first column and the 8th column.
This is the query I have created so far to resolve the values of WeatherDependent:
SELECT CFS1.Name as 'weather', *
FROM FSM_CustomForm_693 t
LEFT JOIN FSM_CustomFormSelectOptions CFS1 ON CFS1.ID = t.WeatherDependent
where t.ID = 24
Ultimately I need to have the data look like this:
weather ID MemberID SubscriptionID DateEntered ParticipatedBefore ParticipatedBeforeCities WeatherDependent NonRefundable TShirtSize HearAboutEvent
Yes 24 18 1 2013-12-19 0 NULL 10950 10952 10957 Facebook, radio, commercial
Things I think you could use to accomplish this are:
A Split TVF FUNCTION - http://msdn.microsoft.com/en-us/library/ms186755.aspx
CROSS APPLY - http://technet.microsoft.com/en-us/library/ms175156.aspx
STUFF & FOR XML PATH - http://msdn.microsoft.com/en-us/library/ms188043.aspx & http://msdn.microsoft.com/en-us/library/ms190922.aspx
Going one step further, you need something like this:
Excuse my profuse use of sub queries.
CREATE FUNCTION dbo.Split (#sep char(1), #s varchar(512))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep, #s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(#sep, #s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
SUBSTRING(#s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
FROM Pieces
)
GO
SELECT
O.A,O.B,O.C,O.D,O.E,O.F,O.G,O.H,O.I,O.J,O.Stuffed
FROM (
SELECT
*
,STUFF((
SELECT ', ' + Name
FROM (
SELECT
V.*
,Y.Name
FROM (
SELECT
'Yes' AS A
,24 AS B
,18 AS C
,1 AS D
,'2013-12-19' AS E
,0 AS F
,NULL AS G
,10950 AS H
,10952 AS I
,10957 AS J
,'11273, 11274, 11275' AS K
)
AS V
CROSS APPLY dbo.Split(',',REPLACE(K,' ','')) AS P
JOIN (
SELECT 11273 AS Id , 'Facebook' AS Name UNION ALL
SELECT 11274 AS Id , 'radio' AS Name UNION ALL
SELECT 11275 AS Id , 'commercial' AS Name
)Y ON y.Id = p.s) ExampleTable
FOR XML PATH('')
), 1, 1, '' )
AS [Stuffed]
FROM (
SELECT
V.*
FROM (
SELECT
'Yes' AS A
,24 AS B
,18 AS C
,1 AS D
,'2013-12-19' AS E
,0 AS F
,NULL AS G
,10950 AS H
,10952 AS I
,10957 AS J
,'11273, 11274, 11275' AS K
)
AS V
CROSS APPLY dbo.Split(',',REPLACE(K,' ','')) AS P
JOIN (
SELECT 11273 AS Id , 'Facebook' AS Name UNION ALL
SELECT 11274 AS Id , 'radio' AS Name UNION ALL
SELECT 11275 AS Id , 'commercial' AS Name
)Y ON y.Id = p.s
)Z
) O
GROUP BY O.A,O.B,O.C,O.D,O.E,O.F,O.G,O.H,O.I,O.J,O.K,O.Stuffed

Mysql Query to find distinct characters in a string

Is there a way to write recursive query in mysql. Equivalent of connect by (level or Prior) in oracle. I searched google as well as stackoverflow and there is no direct eqivalent. But is there any work around to get it.
I have a string, i have to iterate through individual characters in the string and print only the distinct characters of the string.
Input:
recursive
Output:
recusiv
I came up with this "simple" solution.
Functions used:
GROUP_CONCAT: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
SUBSTRING http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring
Live demo: http://www.sqlfiddle.com/#!2/d41d8/19186
SELECT
GROUP_CONCAT( chars.c SEPARATOR '') AS allchars
FROM (
SELECT DISTINCT
SUBSTRING( str.str, pos.pos, 1 ) AS c
FROM
( SELECT x1.x + x2.x*10 AS pos
FROM
( SELECT 0 AS x UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9
) AS x1
INNER JOIN
( SELECT 0 AS x UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9
) AS x2
) AS pos
INNER JOIN
( SELECT 'recursive' AS str UNION ALL
SELECT 'XYZ'
) AS str
) AS chars