2 SQL queries at once - mysql

How can I concatenate these two queries, so that I can have 3 columns in my result: postcode, memberCount and placeCount
SELECT LEFT(`delivery_postcode`, 2) as `postcode`, count(`delivery_postcode`) as `count`
FROM `customer_cards`
WHERE `delivery_postcode` IS NOT NULL
AND `delivery_postcode` <> ''
GROUP BY `postcode`
ORDER BY `count` DESC
and
SELECT LEFT(`placePostcode`, 2) as `postcode`, count(`placePostcode`) as `placeCount`
FROM `RestaurantsForGoogleMaps`
WHERE `placePostcode` IS NOT NULL
AND `placePostcode` <> ''
GROUP BY `postcode`
ORDER BY `placeCount` DESC
At the moment my results look like the following, for either query
postcode | count/placeCount
------------------------
SW | 817
W1 | 533
EC | 395

Something like this should work:
SELECT LEFT(`delivery_postcode`, 2) as `postcode`
, count(`delivery_postcode`) as `count`
, pc.placeCount
FROM `customer_cards` cc
LEFT JOIN (
SELECT LEFT(`placePostcode`, 2) as `postcode`,
count(`placePostcode`) as `placeCount`
FROM `RestaurantsForGoogleMaps`
WHERE `placePostcode` IS NOT NULL
AND `placePostcode` <> ''
GROUP BY `postcode`
) pc
on pc.postcode = LEFT(cc.delivery_postcode, 2)
WHERE `delivery_postcode` IS NOT NULL
AND `delivery_postcode` <> ''
GROUP BY `postcode`
ORDER BY `count` DESC

SELECT postcode,count,placecount FROM (SELECT LEFT(`delivery_postcode`, 2) as `postcode`, count(`delivery_postcode`) as `count`, 0 as `placecount`
FROM `customer_cards`
WHERE `delivery_postcode` IS NOT NULL
AND `delivery_postcode` <> ''
GROUP BY `postcode`
UNION
SELECT LEFT(`placePostcode`, 2) as `postcode`, count(`placePostcode`) as `placecount`,0 as `count`
FROM `RestaurantsForGoogleMaps`
WHERE `placePostcode` IS NOT NULL
AND `placePostcode` <> ''
GROUP BY `postcode` ) ORDER BY count desc

At the moment my results look like the following, for either query
;WITH PC1 AS (
SELECT LEFT(`delivery_postcode`, 2) as `postcode`, count(`delivery_postcode`) as `count`
FROM `customer_cards`
WHERE `delivery_postcode` IS NOT NULL
AND `delivery_postcode` <> ''
GROUP BY `postcode`
ORDER BY `count` DESC
),
PC2 AS (
SELECT LEFT(`placePostcode`, 2) as `postcode`, count(`placePostcode`) as `placeCount`
FROM `RestaurantsForGoogleMaps`
WHERE `placePostcode` IS NOT NULL
AND `placePostcode` <> ''
GROUP BY `postcode`
ORDER BY `placeCount` DESC
)
SELECT a.postcode, a.count,b.placeCount
FROM PC1 a
LEFT JOIN PC2 b
ON a.postcode = b.postcode

Create both queries as an inline views and then join on postcode. This assumes both queries return the desired results and that POST CODE is the key on which to join and there are no other attributes needing to complete the join properly. It also assumes the post code would be in both tables.
If not, then we have to replicate the join as right and left and union the results together.
SELECT A.postcode, A.mcount, B.placecount
FROM
(SELECT LEFT(delivery_postcode, 2) as postcode, count(delivery_postcode) as mcount
FROM customer_cards
WHERE delivery_postcode IS NOT NULL
AND delivery_postcode <> ''
GROUP BY LEFT(delivery_postcode, 2)) A
INNER JOIN (
SELECT LEFT(placePostcode, 2) as postcode, count(placePostcode) as placeCount
FROM RestaurantsForGoogleMaps
WHERE placePostcode IS NOT NULL
AND placePostcode <> ''
GROUP BY LEFT(placePostcode, 2)) B
on A.postcode = B.postcode
order by A.postcode

Related

MySQL said: #1241 - Operand should contain 1 column(s)

SELECT
student.Student_Name
FROM
`student`
GROUP BY
student.Student_ID,
teacher.Department_No IN (
SELECT
teacher.Department_No
FROM
`teacher`, `building`
WHERE
teacher.Department_No BETWEEN 1000
AND 2999
GROUP BY
teacher.Department_No = (
SELECT
*
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
)
) LIMIT 0, 25
Your sql has two issues:
You need to use IN instead of = OR limit the subquery to only one record
You need to use a specify column instead of * in the subquery
use IN
teacher.Department_No IN (
SELECT
Department_No
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
)
use LIMIT
teacher.Department_No = (
SELECT
Department_No
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
LIMIT 1
)
You need to select one column like deparment_id in subquery part
SELECT
student.Student_Name
FROM
`student`
GROUP BY
student.Student_ID,
teacher.Department_No IN (
SELECT
teacher.Department_No
FROM
`teacher`, `building`
WHERE
teacher.Department_No BETWEEN 1000
AND 2999
GROUP BY
teacher.Department_No = (
SELECT
department_id
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
)
) LIMIT 0, 25

Mysql clear code in one line

i was searching on google and in stackoverflow.com how can i write this code clearly and nice but found nothing.
Any idea?
MySQL query:
SELECT COUNT(*) AS `allInvoice`,
(SELECT COUNT(*) FROM `ocr_entity` WHERE `status` = 0) AS `new`,
(SELECT COUNT(*) FROM `ocr_entity` WHERE `status` = 10) AS `notTemplate`,
(SELECT COUNT(*) FROM `ocr_entity` WHERE `status` = 50) AS `withMistake`,
(SELECT COUNT(*) FROM `ocr_entity` WHERE `status` = 100) AS `finished`,
(SELECT COUNT(*) FROM `ocr_entity` WHERE `status` = 200) AS `skipped`
FROM `ocr_entity`;
Use conditional aggregation:
SELECT COUNT(*) AS `allInvoice`,
SUM( `status` = 0 ) AS `new`,
SUM( `status` = 10 ) AS `notTemplate`,
SUM( `status` = 50 ) AS `withMistake`,
SUM( `status` = 100 ) AS `finished`,
SUM( `status` = 200 ) AS `skipped`
FROM `ocr_entity`;
MySQL treats booleans as numbers in a numeric context, with 0 for false and 1 for true (which is why SUM() works).

Join Queries together in one

I have a two queries that I joined together with UNION ALL to do a count one for mobile leads and the other for web leads. But not exactly sure how to join the two results into one. Here is my query:
SELECT CAST( submitdate AS DATE ) as submitdate, COUNT( DISTINCT name, email, phone, `make` , `model` , `mdlyr` , `miles` ) AS webcount FROM leads WHERE email <> '' and mobile = '0' GROUP BY CAST( submitdate AS DATE )
UNION ALL
SELECT CAST( submitdate AS DATE ) as submitdate, COUNT( DISTINCT name, email, phone, `make` , `model` , `mdlyr` , `miles` ) AS mobilecount FROM leads WHERE email <> '' and mobile = '1' GROUP BY CAST( submitdate AS DATE )
But my results are two columns that says submitdate, webcount and the dates are duplicated and with counts next to them like this:
submitdate | webcount
2014-03-19 | 30
2014-03-19 | 15
2014-03-18 | 59
2014-03-18 | 37
When I am trying to get it to look like this:
submitdate | webcount | mobilecount
2014-03-19 | 30 | 15
2014-03-18 | 59 | 37
What am I doing wrong?
Here is a pivot approach. Use your union, but as a "PreQuery". I added one extra column to identify the origin as web or mobile by a character. From that, I use that at the outer level and do a group by date, but a sum of whatever count, but only based on the web or mobile flag value.
select
PQ.submitdate,
sum( case when PQ.leadOrigin = 'W' then PQ.DateCnt else 0 end ) as WebCount,
sum( case when PQ.leadOrigin = 'M' then PQ.DateCnt else 0 end ) as MobileCount
from
( SELECT
CAST( submitdate AS DATE ) as submitdate,
MAX( 'W' ) as leadOrigin,
COUNT( DISTINCT name, email, phone, `make` , `model` , `mdlyr` , `miles` ) AS DateCnt
FROM
leads
WHERE
email <> ''
and mobile = '0'
GROUP BY
CAST( submitdate AS DATE )
UNION ALL
SELECT
CAST( submitdate AS DATE ) as submitdate,
MAX( 'M' ) as leadOrigin,
COUNT( DISTINCT name, email, phone, `make` , `model` , `mdlyr` , `miles` ) AS DateCnt
FROM
leads
WHERE email <> ''
and mobile = '1'
GROUP BY CAST( submitdate AS DATE ) ) PQ
group by
PQ.submitdate
I was able to do this query:
SELECT a.submitdate, b.webcount, c.mobilecount
FROM (
SELECT DISTINCT CAST( submitdate AS DATE ) AS submitdate FROM leads) AS a
INNER JOIN
(SELECT CAST( submitdate AS DATE ) AS submitdate, COUNT( DISTINCT name, email, phone, `make` , `model` , `mdlyr` , `miles` ) AS webcount FROM leads WHERE email <> '' AND mobile = '0' GROUP BY CAST( submitdate AS DATE )) AS b ON a.submitdate = b.submitdate
INNER JOIN
(SELECT CAST( submitdate AS DATE ) AS submitdate, COUNT( DISTINCT name, email, phone, `make` , `model` , `mdlyr` , `miles` ) AS mobilecount FROM leads WHERE email <> '' AND mobile = '1' GROUP BY CAST( submitdate AS DATE )) AS c ON b.submitdate = c.submitdate
ORDER BY a.submitdate DESC
But it only gives me dates from 3/16/2014, which is when Mobile has a count higher than 0. Is there something to add to this that will include all dates and default to 0 if there is none?

How to merge the result of this 2 queries in mysql server

I am actually stuck in merging the result of this two queries:
first query:
SELECT c.code, c.name, pc.sku, pc.cat_code, pp.title
FROM `cat_parent` cp, cat c, prod_cat pc, products pp
WHERE c.code = cp.cat_code
AND cp.cat_code = pc.cat_code
AND pp.sku = pc.sku
AND cp.parent_code = 01110
AND hide =0
The result I get is:
Second query:
SELECT `sku` , `update_date` , `description` , count( * ) AS total_sold
FROM `orderline`
WHERE `update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( sku, 7 )
ORDER BY total_sold DESC
The result:
The question I want to ask that how can I get the result by filtering the sku available in both tables.
Just bit confused on that part....any ideas will be appreciated.
This is only part of the data. there is heaps of data. Yes, I want to merge the both tables and want to find the common sku available in both tables.
My expected result will be sku, title, total sold.
Thanks, anyway I managed to get around to get the result.
My final query:
SELECT * FROM (
SELECT sku , update_date , description FROM orderline WHERE
update_date >= '2012-03-06' AND update_date <= '2012-03-07' )g
JOIN (
SELECT c.code, c.name, pc.sku, pc.cat_code FROM cat_parent cp, cat
c, prod_cat pc, products pp WHERE c.code = cp.cat_code AND cp.cat_code
= pc.cat_code AND pp.sku = pc.sku AND cp.parent_code =01110 AND hide =0 )p ON left( g.sku, 7 ) = left( p.sku, 7 )
Something like this -
SELECT
`c`.`code`, `c`.`name`, `pc`.`sku`, `pc`.`cat_code`, `pp.title`,
`ol`.`sku`, `ol`.`update_date`, `ol`.`description`, COUNT(*) AS `total_sold`
FROM `cat_parent` `cp`
INNER JOIN `cat` `c`
ON `c`.`code` = `cp`.`cat_code`
INNER JOIN `prod_cat` `pc`
ON `cp`.`cat_code` = `pc`.`cat_code`
INNER JOIN `products` `pp`
ON `pp`.`sku` = `pc`.`sku`
INNER JOIN `orderline` `ol`
ON LEFT(`pc`.`sku`, 7) = LEFT(`ol`.`sku`, 7)
WHERE `cp`.`parent_code` = 01110
AND `hide` = 0
AND `ol`.`update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `ol`.`update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( `ol`.`sku`, 7 )
ORDER BY `total_sold` DESC

Why can i sort an inline SELECT value but not use it in a WHERE clause?

I have this small SQL query.
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
AND `grade` >= 5
ORDER BY `grade` DESC
This gives me the error
1054 - Unknown column 'grade' in 'where clause'
But if i remove the 2nd last line, it works fine. I have tried to do AND a.grade and even give the tests table a name and append that name to grade but still no luck.
How can I use this inline query in a WHERE clause?
I have found that this works, but is it the only way?
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
AND (
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) >= 5
ORDER BY `grade` DESC
Sql statements are somewhat evaluated in the following order:
FROM
WHERE
SELECT
GROUP
HAVING
ORDER
So things you define in the SELECT-clause are not available in the WHERE-clause. You would need to put that constraint into a HAVING-clause:
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
HAVING `grade` >= 5
ORDER BY `grade` DESC
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
HAVING `grade` >= 5
ORDER BY
`grade` DESC