I have this crazy nested sql statement and it returns something like this:
However, what I want is to use this data in the image to return 2 columns. col_1:SUM(avgWithCriteria)/43 and col_2:SUM(avgWithoutCriteria)/43. How can I do this by adding onto my query below?
SELECT
( ( avgWithCriteria - totalAverage ) / ( ( avgWithCriteria + totalAverage ) / 2 ) ) * 100 as percentDifference,
a.*
FROM
(SELECT
AVG( CASE WHEN 'f' not in ( has_free_parking ) THEN price ELSE null END) as avgWithCriteria,
AVG( CASE WHEN 'f' in ( has_free_parking ) THEN price ELSE null END) as avgWithoutCriteria,
AVG( price ) as totalAverage,
neighbourhood_cleansed
FROM listings
WHERE city_name="berlin"
AND price <= 1000000
AND price >= -1
AND reviews_per_month <= 1000000
AND reviews_per_month >= -1
AND est_monthly_income <= 1000000
AND est_monthly_income >= -1
GROUP BY neighbourhood_cleansed ) a;
Try this:-
SELECT percentDifference,avgWithCriteria,avgWithoutCriteria,totalAverage,neighbourhood_cleansed,
(col1_1/43) as col1,(col2_2/43) as col2
from
(
SELECT a.*,SUM(avgWithCriteria) as col1_1,SUM(avgWithoutCriteria) as col2_2
FROM
(
SELECT
( ( avgWithCriteria - totalAverage ) / ( ( avgWithCriteria + totalAverage ) / 2 ) ) * 100 as percentDifference,
a.*
FROM
(SELECT
AVG( CASE WHEN 'f' not in ( has_free_parking ) THEN price ELSE null END) as avgWithCriteria,
AVG( CASE WHEN 'f' in ( has_free_parking ) THEN price ELSE null END) as avgWithoutCriteria,
AVG( price ) as totalAverage,
neighbourhood_cleansed
FROM listings
WHERE city_name="berlin"
AND price <= 1000000
AND price >= -1
AND reviews_per_month <= 1000000
AND reviews_per_month >= -1
AND est_monthly_income <= 1000000
AND est_monthly_income >= -1
GROUP BY neighbourhood_cleansed ) a
) a
GROUP BY percentDifference,avgWithCriteria,avgWithoutCriteria,totalAverage,neighbourhood_cleansed
) a;
SELECT
( ( avgWithCriteria - totalAverage ) / ( ( avgWithCriteria + totalAverage ) / 2 ) ) * 100 as percentDifference,
SUM(avgWithCriteria)/43 AS col_1,
SUM(avgWithoutCriteria)/43 AS col_2,
a.*
FROM
(SELECT
AVG( CASE WHEN 'f' not in ( has_free_parking ) THEN price ELSE null END) as avgWithCriteria,
AVG( CASE WHEN 'f' in ( has_free_parking ) THEN price ELSE null END) as avgWithoutCriteria,
AVG( price ) as totalAverage,
neighbourhood_cleansed
FROM listings
WHERE city_name="berlin"
AND price <= 1000000
AND price >= -1
AND reviews_per_month <= 1000000
AND reviews_per_month >= -1
AND est_monthly_income <= 1000000
AND est_monthly_income >= -1
GROUP BY neighbourhood_cleansed ) a;
I am trying to answer the question:
How often does a character occur in the first position versus the
second position of a string?
using a SQL query on Mysql.
However I get a syntax error.
The code:
SELECT
onechar,
ASCII(onechar) as asciival,
COUNT(*) as cnt,
SUM(CASE WHEN pos = 1 THEN 1 ELSE 0 END) as pos_1,
SUM(CASE WHEN pos = 2 THEN 1 ELSE 0 END) as pos_2
FROM (
(SELECT
SUBSTRING(`city`, 1, 1) as onechar,
1 as pos
FROM `orders`
WHERE LEN(`city` >= 1 )
UNION ALL
(SELECT
SUBSTRING(`city`, 2, 1) as onechar,
2 as pos
FROM `orders`
WHERE LEN(`city` >= 2)
)
GROUP BY onechar
ORDER BY onechar
The error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'GROUP BY onechar ORDER BY onechar LIMIT 0, 30' at line 1
Tried several ways without success.
Anyone could give me a light on this problem?
The parenthesis look incorrect and the query is missing an alias for the derived table. Also, because mysql evaluates booleans to 1 or 0 you can simplify your sum statements. Try this:
SELECT onechar, ASCII(onechar) as asciival, COUNT(*) as cnt,
SUM(pos = 1) as pos_1,
SUM(pos = 2) as pos_2
FROM (
SELECT SUBSTRING(`city`, 1, 1) as onechar, 1 as pos
FROM `orders` WHERE LENGTH(`city`) >= 1
UNION ALL
SELECT SUBSTRING(`city`, 2, 1) as onechar, 2 as pos
FROM `orders` WHERE LENGTH(`city`) >= 2
) t
GROUP BY onechar
ORDER BY onechar
You missed a number of closing bracket.
FROM (
(SELECT
SUBSTRING(`city`, 1, 1) as onechar,
1 as pos
FROM `orders`
WHERE LEN(`city` >= 1 )
)
UNION ALL
(SELECT
SUBSTRING(`city`, 2, 1) as onechar,
2 as pos
FROM `orders`
WHERE LEN(`city` >= 2)
)
)
I currently have a somewhat large SQL statement that UNIONs the same SELECT statement 3 times each time with a larger date range. IE Last 30 days, Last 90 Days and Last 180 Days. The SQL works just fine and I am even OK with the fact that the query takes quite a while to run, I am just wondering if there is anyway to do the same thing with just one SELECT statement.
Seeing as a couple of people asked to see my code:-
SELECT mdt_userid AS logging_officer,
'Last 30 Days' AS timespan,
ACD_Time,
TRUNCATE (( 1 - ( (TotalAssisting+TotalBRB+TotalShift+TotalLunch+TotalBreak-IF(TotalLunch<(DaysLoggedIn*Lunch),TotalLunch,(DaysLoggedIn*Lunch))-IF((TotalBRB+TotalBreak)<(DaysLoggedIn*1800),(TotalBRB+TotalBreak),(DaysLoggedIn*1800))) / (TotalLoginTime-TotalEreq-TotalDefault) ) ) *100,2) AS Utilization_percent,
TRUNCATE((GRS_total/calls)*100,1) AS Ratio,
IF (TotalACW =0,0,TotalACW / calls) AS ACW,
grs.percent AS percent,
TRUNCATE (((grs_total - wo_ci) / grs_total) *100,2) AS percent_w_ci,
TRUNCATE (calls / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS call_per_hour,
TRUNCATE (GRS_total / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS grs_per_hour
FROM (SELECT DISTINCT fullname,
SUM( IF (ReasonCode = '138', `ReasonCodeDuration` , 0) ) AS TotalAssisting,
SUM( IF (ReasonCode = '146', `ReasonCodeDuration` , 0) ) AS TotalBRB,
SUM( IF (ReasonCode = '143', `ReasonCodeDuration` , 0) ) AS TotalShift,
SUM( IF (ReasonCode = '141', `ReasonCodeDuration` , 0) ) AS TotalACW,
SUM( IF (ReasonCode = '231', `ReasonCodeDuration` , 0) ) AS TotalEreq,
SUM( IF (ReasonCode = '0', `ReasonCodeDuration` , 0) ) AS TotalDefault,
COUNT(ReasonCode = '136') AS CountLunch,
SUM( IF (ReasonCode = '136', `ReasonCodeDuration` , 0) ) AS TotalLunch,
SUM( IF (ReasonCode = '137', `ReasonCodeDuration` , 0) ) AS TotalBreak,
SUM( `ReasonCodeDuration` ) AS NRduration
FROM `CiscoAgentNotready`
WHERE StartDate >= '".adjustdate($DateTo,0,0,-30)." 00:00:00'
AND StartDate <= '".$DateTo." 23:59:59'
GROUP BY fullname)
AS notready,
(SELECT DISTINCT agentname,
SUM( loginduration ) AS TotalLoginTime, COUNT(Date(logondate)) as DaysLoggedIn
FROM CiscoAgentLogintime
WHERE logondate >= '".adjustdate($DateTo,0,0,-30)." 00:00:00'
AND logondate <= '".$DateTo." 23:59:59'
GROUP BY agentname)
AS logintime,
(SELECT DISTINCT full_name,
SUM( handled ) AS calls
FROM `CiscoAgentCalls`
WHERE DateCol >= '".adjustdate($DateTo,0,0,-30)."'
AND DateCol <= '".$DateTo."'
GROUP BY full_name)
AS calls,
(SELECT DISTINCT logging_officer,
SUM( first_call ) AS firstcall,
SUM(IF (Config_item = 'unknown', 1, 0) ) AS wo_ci,
COUNT( * ) AS GRS_total,
TRUNCATE ((SUM( first_call ) / COUNT( * )) *100,2) AS percent
FROM (SELECT logging_officer,
IF (logging_officer = `Resolving_Officer` , 1, 0) AS first_call,
Config_item
FROM `callcentergrsdata`
WHERE log_Date >= '".adjustdate($DateTo,0,0,-30)." 00:00:00'
AND log_Date <= '".$DateTo." 23:59:59')
AS a
GROUP BY logging_officer)
AS grs,
(SELECT DISTINCT agtName,
SUM(TalkTime) as sumTalk,
SUM(CallsHandled) as answered,
SUM(TalkTime)/SUM(CallsHandled) as ACD_Time
FROM (SELECT CONCAT( LastName, ', ', FirstName ) AS agtName,
TalkTime,
CallsHandled
FROM `CiscoAgentAHT`
WHERE DateCol >= '".adjustdate($DateTo,0,0,-30)."'
AND DateCol <= '".$DateTo."') as subAHT
GROUP BY agtName)
AS AHT,
techjtblnew
WHERE mdt_userid = '".$user."'
AND notready.fullname = logintime.agentname
AND calls.full_name = notready.fullname
AND calls.full_name = AHT.agtName
AND techjtblnew.cisco = notready.fullname
AND grs.logging_officer = techjtblnew.grs
UNION
SELECT mdt_userid AS logging_officer,
'Last 90 Days' AS timespan,
ACD_Time,
TRUNCATE (( 1 - ( (TotalAssisting+TotalBRB+TotalShift+TotalLunch+TotalBreak-IF(TotalLunch<(DaysLoggedIn*Lunch),TotalLunch,(DaysLoggedIn*Lunch))-IF((TotalBRB+TotalBreak)<(DaysLoggedIn*1800),(TotalBRB+TotalBreak),(DaysLoggedIn*1800))) / (TotalLoginTime-TotalEreq-TotalDefault) ) ) *100,2) AS Utilization_percent,
TRUNCATE((GRS_total/calls)*100,1) AS Ratio,
IF (TotalACW =0,0,TotalACW / calls) AS ACW,
grs.percent AS percent,
TRUNCATE (((grs_total - wo_ci) / grs_total) *100,2) AS percent_w_ci,
TRUNCATE (calls / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS call_per_hour,
TRUNCATE (GRS_total / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS grs_per_hour
FROM (SELECT DISTINCT fullname,
SUM( IF (ReasonCode = '138', `ReasonCodeDuration` , 0) ) AS TotalAssisting,
SUM( IF (ReasonCode = '146', `ReasonCodeDuration` , 0) ) AS TotalBRB,
SUM( IF (ReasonCode = '143', `ReasonCodeDuration` , 0) ) AS TotalShift,
SUM( IF (ReasonCode = '141', `ReasonCodeDuration` , 0) ) AS TotalACW,
SUM( IF (ReasonCode = '231', `ReasonCodeDuration` , 0) ) AS TotalEreq,
SUM( IF (ReasonCode = '0', `ReasonCodeDuration` , 0) ) AS TotalDefault,
COUNT(ReasonCode = '136') AS CountLunch,
SUM( IF (ReasonCode = '136', `ReasonCodeDuration` , 0) ) AS TotalLunch,
SUM( IF (ReasonCode = '137', `ReasonCodeDuration` , 0) ) AS TotalBreak,
SUM( `ReasonCodeDuration` ) AS NRduration
FROM `CiscoAgentNotready`
WHERE StartDate >= '".adjustdate($DateTo,0,0,-90)." 00:00:00'
AND StartDate <= '".$DateTo." 23:59:59'
GROUP BY fullname)
AS notready,
(SELECT DISTINCT agentname,
SUM( loginduration ) AS TotalLoginTime, COUNT(Date(logondate)) as DaysLoggedIn
FROM CiscoAgentLogintime
WHERE logondate >= '".adjustdate($DateTo,0,0,-90)." 00:00:00'
AND logondate <= '".$DateTo." 23:59:59'
GROUP BY agentname)
AS logintime,
(SELECT DISTINCT full_name,
SUM( handled ) AS calls
FROM `CiscoAgentCalls`
WHERE DateCol >= '".adjustdate($DateTo,0,0,-90)."'
AND DateCol <= '".$DateTo."'
GROUP BY full_name)
AS calls,
(SELECT DISTINCT logging_officer,
SUM( first_call ) AS firstcall,
SUM(IF (Config_item = 'unknown', 1, 0) ) AS wo_ci,
COUNT( * ) AS GRS_total,
TRUNCATE ((SUM( first_call ) / COUNT( * )) *100,2) AS percent
FROM (SELECT logging_officer,
IF (logging_officer = `Resolving_Officer` , 1, 0) AS first_call,
Config_item
FROM `callcentergrsdata`
WHERE log_Date >= '".adjustdate($DateTo,0,0,-90)." 00:00:00'
AND log_Date <= '".$DateTo." 23:59:59')
AS a
GROUP BY logging_officer)
AS grs,
(SELECT DISTINCT agtName,
SUM(TalkTime) as sumTalk,
SUM(CallsHandled) as answered,
SUM(TalkTime)/SUM(CallsHandled) as ACD_Time
FROM (SELECT CONCAT( LastName, ', ', FirstName ) AS agtName,
TalkTime,
CallsHandled
FROM `CiscoAgentAHT`
WHERE DateCol >= '".adjustdate($DateTo,0,0,-90)."'
AND DateCol <= '".$DateTo."') as subAHT
GROUP BY agtName)
AS AHT,
techjtblnew
WHERE mdt_userid = '".$user."'
AND notready.fullname = logintime.agentname
AND calls.full_name = notready.fullname
AND calls.full_name = AHT.agtName
AND techjtblnew.cisco = notready.fullname
AND grs.logging_officer = techjtblnew.grs
UNION
SELECT mdt_userid AS logging_officer,
'Last 120 Days' AS timespan,
ACD_Time,
TRUNCATE (( 1 - ( (TotalAssisting+TotalBRB+TotalShift+TotalLunch+TotalBreak-IF(TotalLunch<(DaysLoggedIn*Lunch),TotalLunch,(DaysLoggedIn*Lunch))-IF((TotalBRB+TotalBreak)<(DaysLoggedIn*1800),(TotalBRB+TotalBreak),(DaysLoggedIn*1800))) / (TotalLoginTime-TotalEreq-TotalDefault) ) ) *100,2) AS Utilization_percent,
TRUNCATE((GRS_total/calls)*100,1) AS Ratio,
IF (TotalACW =0,0,TotalACW / calls) AS ACW,
grs.percent AS percent,
TRUNCATE (((grs_total - wo_ci) / grs_total) *100,2) AS percent_w_ci,
TRUNCATE (calls / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS call_per_hour,
TRUNCATE (GRS_total / ( ((TotalLoginTime-TotalEreq-TotalDefault) /3600) / 8.75 ) ,2) AS grs_per_hour
FROM (SELECT DISTINCT fullname,
SUM( IF (ReasonCode = '138', `ReasonCodeDuration` , 0) ) AS TotalAssisting,
SUM( IF (ReasonCode = '146', `ReasonCodeDuration` , 0) ) AS TotalBRB,
SUM( IF (ReasonCode = '143', `ReasonCodeDuration` , 0) ) AS TotalShift,
SUM( IF (ReasonCode = '141', `ReasonCodeDuration` , 0) ) AS TotalACW,
SUM( IF (ReasonCode = '231', `ReasonCodeDuration` , 0) ) AS TotalEreq,
SUM( IF (ReasonCode = '0', `ReasonCodeDuration` , 0) ) AS TotalDefault,
COUNT(ReasonCode = '136') AS CountLunch,
SUM( IF (ReasonCode = '136', `ReasonCodeDuration` , 0) ) AS TotalLunch,
SUM( IF (ReasonCode = '137', `ReasonCodeDuration` , 0) ) AS TotalBreak,
SUM( `ReasonCodeDuration` ) AS NRduration
FROM `CiscoAgentNotready`
WHERE StartDate >= '".adjustdate($DateTo,0,0,-120)." 00:00:00'
AND StartDate <= '".$DateTo." 23:59:59'
GROUP BY fullname)
AS notready,
(SELECT DISTINCT agentname,
SUM( loginduration ) AS TotalLoginTime, COUNT(Date(logondate)) as DaysLoggedIn
FROM CiscoAgentLogintime
WHERE logondate >= '".adjustdate($DateTo,0,0,-120)." 00:00:00'
AND logondate <= '".$DateTo." 23:59:59'
GROUP BY agentname)
AS logintime,
(SELECT DISTINCT full_name,
SUM( handled ) AS calls
FROM `CiscoAgentCalls`
WHERE DateCol >= '".adjustdate($DateTo,0,0,-120)."'
AND DateCol <= '".$DateTo."'
GROUP BY full_name)
AS calls,
(SELECT DISTINCT logging_officer,
SUM( first_call ) AS firstcall,
SUM(IF (Config_item = 'unknown', 1, 0) ) AS wo_ci,
COUNT( * ) AS GRS_total,
TRUNCATE ((SUM( first_call ) / COUNT( * )) *100,2) AS percent
FROM (SELECT logging_officer,
IF (logging_officer = `Resolving_Officer` , 1, 0) AS first_call,
Config_item
FROM `callcentergrsdata`
WHERE log_Date >= '".adjustdate($DateTo,0,0,-120)." 00:00:00'
AND log_Date <= '".$DateTo." 23:59:59')
AS a
GROUP BY logging_officer)
AS grs,
(SELECT DISTINCT agtName,
SUM(TalkTime) as sumTalk,
SUM(CallsHandled) as answered,
SUM(TalkTime)/SUM(CallsHandled) as ACD_Time
FROM (SELECT CONCAT( LastName, ', ', FirstName ) AS agtName,
TalkTime,
CallsHandled
FROM `CiscoAgentAHT`
WHERE DateCol >= '".adjustdate($DateTo,0,0,-120)."'
AND DateCol <= '".$DateTo."') as subAHT
GROUP BY agtName)
AS AHT,
techjtblnew
WHERE mdt_userid = '".$user."'
AND notready.fullname = logintime.agentname
AND calls.full_name = notready.fullname
AND calls.full_name = AHT.agtName
AND techjtblnew.cisco = notready.fullname
AND grs.logging_officer = techjtblnew.grs
Seems like you could get away with a complex grouping. E.g., here's a generic way to do it with records:
SELECT
count(*),
MIN(creation)
FROM record
WHERE creation > CURDATE() - INTERVAL 120 DAY
GROUP BY
IF(creation>CURDATE() - INTERVAL 30 DAY,'030',
IF(creation>CURDATE() - INTERVAL 90 DAY,'090',
IF(creation>CURDATE() - INTERVAL 120 DAY,'120',
'OLDER'
)
)
)
You would want to add the records as you go, as each range is exclusive.
Here's a sample output:
+----------+---------------+
| count(*) | MIN(creation) |
+----------+---------------+
| 1472 | 2012-01-08 |
| 2336 | 2011-11-09 |
| 1528 | 2011-10-10 |
| 5336 | 2011-10-10 |
+----------+---------------+
4 rows in set (0.13 sec)
Yes. Just query for the last 180 days and parse it in the software layer.
If you want an indicator of which one each row is, you can use CASE or IF statements:
http://dev.mysql.com/doc/refman/5.0/en/if-statement.html
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list] ...
[ELSE statement_list]
END IF
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
UPDATE
Ok, now that I know what you are going for I can provide a better solution that I believe will fit your needs.
I don't think that there is a way out of doing UNION BUT you if you do the UNION ahead of time adding a column for the various time spans you can just query once on the results.
In this example, I create a column called span during the UNION. The t1 is the resulting "table". Since span is different for each date range, the rows will show up multiple times.
Example Table:
mysql> select * from test;
+----+------------+
| id | when |
+----+------------+
| 1 | 2012-02-01 |
| 2 | 2012-01-01 |
| 3 | 2011-09-01 |
+----+------------+
Query With Unions:
mysql>
-> SELECT *, 1 as 'span' FROM `test` WHERE `when` > '2012-01-15'
-> UNION
-> SELECT *, 2 as 'span' FROM `test` WHERE `when` > '2011-12-15'
-> UNION
-> SELECT *, 3 as 'span' FROM `test` WHERE `when` > '2011-08-15';
+----+------------+------+
| id | when | span |
+----+------------+------+
| 1 | 2012-02-01 | 1 |
| 2 | 2012-01-01 | 2 |
| 1 | 2012-02-01 | 2 |
| 3 | 2011-09-01 | 3 |
| 2 | 2012-01-01 | 3 |
| 1 | 2012-02-01 | 3 |
+----+------------+------+
Query Using That Union (custom SELECT and WHERE t1.id > 0):
mysql>
-> SELECT
-> `id`,
-> `when`,
-> if(`span` = 1, 'Last 30 Days',
-> if(`span` = 2, 'Last 60 Days',
-> 'Last 180 Days')) as 'Timespan'
-> FROM (
-> SELECT *, 1 as 'span' FROM `test` WHERE `when` > '2012-01-15'
-> UNION
-> SELECT *, 2 as 'span' FROM `test` WHERE `when` > '2011-12-15'
-> UNION
-> SELECT *, 3 as 'span' FROM `test` WHERE `when` > '2011-08-15'
-> ) as t1
-> WHERE t1.id > 0;
+----+------------+---------------+
| id | when | Timespan |
+----+------------+---------------+
| 1 | 2012-02-01 | Last 30 Days |
| 2 | 2012-01-01 | Last 60 Days |
| 1 | 2012-02-01 | Last 60 Days |
| 3 | 2011-09-01 | Last 180 Days |
| 2 | 2012-01-01 | Last 180 Days |
| 1 | 2012-02-01 | Last 180 Days |
+----+------------+---------------+
You will do all of your query stuff off of t1, not off the table itself. Adding the extra column in the creation of t1 allows each row to appear multiple times as the extra row will cause it to be unique.