MySQL count(*) everyday in a month returns [BLOB-2B] instead of number - mysql

I'm going to count every rows each day in a month with a specific user id(vwr_tid). Everything works fine - the result shows up in a table but one thing. A count each days doesn't comes up. It becomes [BLOB-xx] instead of number of rows that day. Here is my code :
SELECT MONTH_v, YEAR_V,
GROUP_CONCAT(IF(day_v=1, views, null)) AS '1',
GROUP_CONCAT(IF(day_v=2, views, null)) AS '2',
GROUP_CONCAT(IF(day_v=3, views, null)) AS '3',
GROUP_CONCAT(IF(day_v=4, views, null)) AS '4',
GROUP_CONCAT(IF(day_v=5, views, null)) AS '5',
GROUP_CONCAT(IF(day_v=6, views, null)) AS '6',
GROUP_CONCAT(IF(day_v=7, views, null)) AS '7',
GROUP_CONCAT(IF(day_v=8, views, null)) AS '8',
GROUP_CONCAT(IF(day_v=9, views, null)) AS '9',
GROUP_CONCAT(IF(day_v=10, views, null)) AS '10',
GROUP_CONCAT(IF(day_v=11, views, null)) AS '11',
GROUP_CONCAT(IF(day_v=12, views, null)) AS '12',
GROUP_CONCAT(IF(day_v=13, views, null)) AS '13',
GROUP_CONCAT(IF(day_v=14, views, null)) AS '14',
GROUP_CONCAT(IF(day_v=15, views, null)) AS '15',
GROUP_CONCAT(IF(day_v=16, views, null)) AS '16',
GROUP_CONCAT(IF(day_v=17, views, null)) AS '17',
GROUP_CONCAT(IF(day_v=18, views, null)) AS '18',
GROUP_CONCAT(IF(day_v=19, views, null)) AS '19',
GROUP_CONCAT(IF(day_v=20, views, null)) AS '20',
GROUP_CONCAT(IF(day_v=21, views, null)) AS '21',
GROUP_CONCAT(IF(day_v=22, views, null)) AS '22',
GROUP_CONCAT(IF(day_v=23, views, null)) AS '23',
GROUP_CONCAT(IF(day_v=24, views, null)) AS '24',
GROUP_CONCAT(IF(day_v=25, views, null)) AS '25',
GROUP_CONCAT(IF(day_v=26, views, null)) AS '26',
GROUP_CONCAT(IF(day_v=27, views, null)) AS '27',
GROUP_CONCAT(IF(day_v=28, views, null)) AS '28',
GROUP_CONCAT(IF(day_v=29, views, null)) AS '29',
GROUP_CONCAT(IF(day_v=30, views, null)) AS '30',
GROUP_CONCAT(IF(day_v=31, views, null)) AS '31'
FROM
(
SELECT DAY(vwr_date) AS day_v,
MONTH(vwr_date) AS MONTH_v,
Year(vwr_date) AS YEAR_V,
date(vwr_date) AS date_v,
count(vwr_id) AS views
FROM car_viewer
WHERE Year(vwr_date)='2012' AND vwr_tid='18'
GROUP BY date_v
) as viewz
GROUP BY MONTH_v, YEAR_V
ORDER BY MONTH_v, YEAR_V DESC
The script is updated from #rs : Count record each day of a month from mysql into html table
The result.

I don't see the need for GROUP_CONCAT(), when SUM() will serve your needs:
SELECT MONTH_v, YEAR_V,
SUM(IF(day_v=1, views, 0)) AS '1',
SUM(IF(day_v=2, views, 0)) AS '2',
SUM(IF(day_v=3, views, 0)) AS '3',
SUM(IF(day_v=4, views, 0)) AS '4',
SUM(IF(day_v=5, views, 0)) AS '5',
SUM(IF(day_v=6, views, 0)) AS '6',
SUM(IF(day_v=7, views, 0)) AS '7',
SUM(IF(day_v=8, views, 0)) AS '8',
SUM(IF(day_v=9, views, 0)) AS '9',
SUM(IF(day_v=10, views, 0)) AS '10',
SUM(IF(day_v=11, views, 0)) AS '11',
SUM(IF(day_v=12, views, 0)) AS '12',
SUM(IF(day_v=13, views, 0)) AS '13',
SUM(IF(day_v=14, views, 0)) AS '14',
SUM(IF(day_v=15, views, 0)) AS '15',
SUM(IF(day_v=16, views, 0)) AS '16',
SUM(IF(day_v=17, views, 0)) AS '17',
SUM(IF(day_v=18, views, 0)) AS '18',
SUM(IF(day_v=19, views, 0)) AS '19',
SUM(IF(day_v=20, views, 0)) AS '20',
SUM(IF(day_v=21, views, 0)) AS '21',
SUM(IF(day_v=22, views, 0)) AS '22',
SUM(IF(day_v=23, views, 0)) AS '23',
SUM(IF(day_v=24, views, 0)) AS '24',
SUM(IF(day_v=25, views, 0)) AS '25',
SUM(IF(day_v=26, views, 0)) AS '26',
SUM(IF(day_v=27, views, 0)) AS '27',
SUM(IF(day_v=28, views, 0)) AS '28',
SUM(IF(day_v=29, views, 0)) AS '29',
SUM(IF(day_v=30, views, 0)) AS '30',
SUM(IF(day_v=31, views, 0)) AS '31'
FROM
(
SELECT DAY(vwr_date) AS day_v,
MONTH(vwr_date) AS MONTH_v,
Year(vwr_date) AS YEAR_V,
date(vwr_date) AS date_v,
count(vwr_id) AS views
FROM car_viewer
WHERE Year(vwr_date)='2012' AND vwr_tid='18'
GROUP BY date_v
) as viewz
GROUP BY MONTH_v, YEAR_V
ORDER BY MONTH_v, YEAR_V DESC;
See http://sqlfiddle.com/#!2/75aa8/1 for a working example.

Related

SQL query to get number of clients with last statement equal connected

I need to make a SQL query
table 'records' structure:
contact_id(integer),
client_id(integer),
worker_id(integer),
statement_status(varchar),
contact_ts(timestamp)
It has to show the following:
current date
number of clients which last statement_status was 'interested'
number of clients which last statement_status was 'not_interested' and previus status was 'not_present'
Could somebody help?
sample data:
contact_id client_id contact_ts worker_id statement_status
'1', '181', '2017-09-24 03:38:31.000000', '107', 'voicemail'
'2', '72', '2017-09-23 09:32:38.000000', '10', 'not_interested'
'3', '277', '2017-09-22 07:06:16.000000', '119', 'interested'
'4', '36', '2017-09-21 04:39:57.000000', '118', 'not_present'
'5', '33', '2017-09-20 04:12:12.000000', '161', 'voicemail'
'6', '244', '2017-09-19 02:26:30.000000', '13', 'not_interested'
'7', '346', '2017-09-18 02:30:35.000000', '255', 'interested'
'8', '128', '2017-09-17 06:20:13.000000', '52', 'not_present'
'9', '33', '2017-09-16 08:58:02.000000', '188', 'not_present'
'10', '352', '2017-09-15 08:18:40.000000', '324', 'not_interested'
'11', '334', '2017-09-14 04:27:40.000000', '373', 'interested'
'12', '2', '2017-09-13 08:44:40.000000', '40', 'not_present'
'13', '33', '2017-09-12 03:46:16.000000', '252', 'voicemail'
'14', '366', '2017-09-11 04:31:22.000000', '78', 'not_interested'
'15', '184', '2017-09-10 06:08:01.000000', '289', 'interested'
'16', '184', '2017-09-09 05:45:56.000000', '124', 'not_present'
'17', '102', '2017-09-08 07:09:30.000000', '215', 'voicemail'
'18', '140', '2017-09-07 08:09:18.000000', '196', 'not_interested'
'19', '315', '2017-09-06 05:13:40.000000', '242', 'interested'
'20', '268', '2017-09-05 07:41:40.000000', '351', 'not_present'
'21', '89', '2017-09-04 05:32:05.000000', '232', 'voicemail'
desired output:
Time, interested, not-interested
2017-09-10 06:08:01, 5, 5
I tried something with sub queries, but it obviously doesn't work:
SELECT
GETDATE()
,(select count(*)
from record a
where (select statement_status
from record
where client_id == a.client_id
order by a.contact_ts
limit 1) == "interested"
group by a.contact_id)
,(select count(*)
from record a
where (select (select statement_status
from record
where client_id == a.client_id
order by a.contact_ts
limit 2) order by a.contact_ts desc limit 1) == "interested"
and
(select statement_status
from record
where client_id == a.client_id
order by a.contact_ts
limit 1) == "interested"
group by a.contact_id)
from record b;
How should I use the inner selects?
I must write a poem, because most of my post is a code.
So maybe something from "Dead man"?
“Don't let the sun burn a hole in your ass, William Blake. Rise now, and drive your cart and plough over the bones of the dead!”
;)
Try something like this:
WITH status AS (
SELECT DISTINCT client_id,
first_value(statement_status) OVER w1 AS last_status,
nth_value(statement_status, 2) OVER w1 AS prev_status
FROM records
WINDOW w1 AS (PARTITION BY client_id ORDER BY contact_ts DESC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
)
SELECT CURRENT_DATE(),
SUM(last_status = 'interested') AS interesed,
SUM(last_status = 'not_interested' AND prev_status = 'not_present') AS not_interested
FROM status

Changing multiple rows to columns (Pivotable) in a table from mysql [duplicate]

Hi i have the following mysql data
INSERT INTO `monthly` (`id`, `year`, `stat_id`, `cat_id`, `January`, `February`, `March`, `April`, `May`, `June`, `July`, `August`, `September`, `October`, `November`, `December`) VALUES
(1, '2017', '12', '25', '1', '3', '1', '1', '3', '4', '4', '2', '4', '', '', ''),
and i would like it to be convert to be like this
INSERT INTO `monthlydata` (`id`, `year`, `monthName`, `stat_id`, `cat_id`, `data`) VALUES
(1, '2017', 'January', '12', '25', '1'),
(2, '2017', 'February', '12', '25', '3'),
(3, '2017', 'March', '12', '25', '1'),
(4, '2017', 'April', '12', '25', '1'),
(5, '2017', 'May', '12', '25', '3'),
(6, '2017', 'June', '12', '25', '4'),
(7, '2017', 'July', '12', '25', '4'),
(8, '2017', 'August', '12', '25', '2'),
(9, '2017', 'September', '12', '25', '4'),
(10, '2017', 'October', '12', '25', ''),
(11, '2017', 'November', '12', '25', ''),
(12, '2017', 'December', '12', '25', ''),
is there an easier way to do this using mysql/php
You need to UNPIVOT your data. MySQL doesn't have a built in function to do that so you'll need to use multiple queries.
INSERT INTO `monthlydata` (`id`, `year`, `monthName`, `stat_id`, `cat_id`, `data`) VALUES
SELECT id, year, 'January', stat_id, cat_id, January
FROM monthly WHERE monthName = 'January'
UNION ALL
SELECT id, year, 'February', stat_id, cat_id, February
FROM monthly WHERE monthName = 'February'
UNION ALL
SELECT id, year, 'March', stat_id, cat_id, March
FROM monthly WHERE monthName = 'March'
.....
ID column here might cause issues. Depending on how you have defined it. If it is auto generated then you can remove it from the INSERT and let it be auto generated. Since you'll have rows for all months with same ID, you need to handle that scenario.

Total in a mysql pivot query

I've this pivot query:
SELECT `fonte`,
MAX(IF(month= '1', sell, NULL)) AS Gen,
MAX(IF(month= '2', sell, NULL)) AS Feb,
MAX(IF(month= '3', sell, NULL)) AS Mar,
MAX(IF(month= '4', sell, NULL)) AS Apr,
MAX(IF(month= '5', sell, NULL)) AS Mag,
MAX(IF(month= '6', sell, NULL)) AS Giu,
MAX(IF(month= '7', sell, NULL)) AS Lug,
MAX(IF(month= '8', sell, NULL)) AS Ago,
MAX(IF(month= '9', sell, NULL)) AS Sett,
MAX(IF(month= '10', sell, NULL)) AS Ott,
MAX(IF(month= '11', sell, NULL)) AS Nov,
MAX(IF(month= '12', sell, NULL)) AS Dic,
FROM `pdl_dati` group by fonte
How can I insert the "total" for month='1' and month='2' and month='3' and month='4' and month='5' and month='6' and month='7' and month='8' and month='9' and month='10' and month='11' and month='12'?
Thanks
If you want a final row that has a total for each month you can use GROUP BY WITH ROLLUP:
SELECT `fonte`,
MAX(IF(month= '1', sell, NULL)) AS Gen, -- do you want this to be sum?
MAX(IF(month= '2', sell, NULL)) AS Feb,
MAX(IF(month= '3', sell, NULL)) AS Mar,
MAX(IF(month= '4', sell, NULL)) AS Apr,
MAX(IF(month= '5', sell, NULL)) AS Mag,
MAX(IF(month= '6', sell, NULL)) AS Giu,
MAX(IF(month= '7', sell, NULL)) AS Lug,
MAX(IF(month= '8', sell, NULL)) AS Ago,
MAX(IF(month= '9', sell, NULL)) AS Sett,
MAX(IF(month= '10', sell, NULL)) AS Ott,
MAX(IF(month= '11', sell, NULL)) AS Nov,
MAX(IF(month= '12', sell, NULL)) AS Dic
FROM `pdl_dati`
group by fonte with ROLLUP;
As a side note, if you are attempting to get the total for each fonte by month, I would think you would want to use sum instead of max. See Demo

SQL query to show top x records with evenly distributed values

I have a database of contacts at companies. Multiple contacts per company in different departments. Each company has turnover and industry data attached to it.
I need to write a query that shows the top 10 most recently added contacts (unix timestamp) but i don't want it to be all Marketing contacts (even if the top 10 are), i would like to look at the top 100 instead and get 10 contacts out that are from different departments. So instead of the top 10 being all marketing, there might be 2 marketing, 2 I.T, 2 HR, 2 Personnel.
So my query basically is this:
SELECT DISTINCT `surname`, `job_title`, `company_name`
FROM (`company_database`)
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13')
AND `turnover_code` IN ('5', '6', '7', '8')
AND `contact_code` IN ('16', '17', '26', '27', '9', '10', '30', '31', '23', '24', '12', '13') AND `industry_code` NOT IN ('22', '17', '35', '36') LIMIT 10
But that simply returns a unique row. What i need is one contact per company and no more than 1 contact_code type. I also only want 10 rows returned, but obviously to get this 1 per contact code per row, the query will need to look at more than 10.
Is this possible in just a query? Or should i do something programatically to apply the logic needed to whittle down the results of a query.
you can work with a temporary table using the myisam engine and a trick.
If you create the following temporary table:
create table tmp_company_sequence
( surname varchar(255)
,job_title varchar(255)
,company_name varchar(255)
,date_added date
,contact_code int
,counter int auto_increment
,primary key (contact_code,counter)
);
Now
insert into `tmp_company_sequence`( `surname`, `job_title`, `company_name`,`contact_code`,`date_added`)
SELECT DISTINCT `surname`, `job_title`, `company_name`,`contact_code`,`date_added`
FROM (`company_database`)
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13')
AND `turnover_code` IN ('5', '6', '7', '8')
AND `contact_code` IN ('16', '17', '26', '27', '9', '10', '30', '31', '23', '24', '12', '13') AND `industry_code` NOT IN ('22', '17', '35', '36')
order by contact_code, added_date desc;
Your temporary table will now hold all the contacts with a counter. The counter is increased for every contact of the same contact_code. SO the newest contact with a certain contact code will have counter = 1, the next recent will have counter = 2 and so on.
You can now do a
select *
from tmp_company_sequence
order by counter asc, date_added desc
limit 10;
This will give you a list of the latest contacts added over all contact_codes.
Edit:
I just realised this could be done with a single query, but it is even more ugly:
SELECT `surname`
, `job_title`
, `company_name`
, `contact_code`
FROM(
SELECT
`surname`
, `job_title`
, `company_name`
, `contact_code`
, `date_added`
, IF(contact_code = #prev_contact_code,#i:=#i+1,#i:=1) AS counter
, #prev_contact_code = contact_code
FROM
(`company_database`)
,(SELECT #i := 1)
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13')
AND `turnover_code` IN ('5', '6', '7', '8')
AND `contact_code` IN (
'16'
, '17'
, '26'
, '27'
, '9'
, '10'
, '30'
, '31'
, '23'
, '24'
, '12'
, '13'
)
AND `industry_code` NOT IN ('22', '17', '35', '36')
ORDER BY contact_code
, added_date DESC) sub
WHERE counter = 1
ORDER BY added_date DESC
LIMIT 10;
This does basically the same as the option with the temporary table, but it creates the counter in the fly by storing data from the previous column in global variables. It is messy but can be used within a single query.

Convert crosstab query into a view

I have the following query which I want to convert to a view:
SELECT
PartNum,
SUM(IF(DAYOFWEEK(DeliveryDate) = '2', value, NULL)) AS 'Mon',
SUM(IF(DAYOFWEEK(DeliveryDate) = '3', value, NULL)) AS 'Tue',
SUM(IF(DAYOFWEEK(DeliveryDate) = '4', value, NULL)) AS 'Wed',
SUM(IF(DAYOFWEEK(DeliveryDate) = '5', value, NULL)) AS 'Thu',
SUM(IF(DAYOFWEEK(DeliveryDate) = '6', value, NULL)) AS 'Fri',
SUM(IF(DAYOFWEEK(DeliveryDate) = '7', value, NULL)) AS 'Sat',
SUM(IF(DAYOFWEEK(DeliveryDate) = '1', value, NULL)) AS 'Sun',
SUM(IF(DeliveryDate > DATE_ADD(CURDATE(),INTERVAL 7 DAY), value, NULL)) AS 'Future'
FROM (
SELECT PartNum, DeliveryDate , SUM(Ordered) value FROM v_archived_items_due
GROUP BY PartNum, DeliveryDate
) t
GROUP BY PartNum;
When I try to save it as a view, I get the following error:
1349 - Views SELECT contains a subquery in the FROM clause.
The query works fine by itself. How do I turn it into a view?
MySQL does not allow subqueries in view so, without seeing any sample data to see how to rework this without the subqyery. Since this is working as expected, I would create a view of your subquery:
create view view1 as
SELECT PartNum, DeliveryDate , SUM(Ordered) value
FROM v_archived_items_due
GROUP BY PartNum, DeliveryDate;
Then just call this view in your query:
SELECT
PartNum,
SUM(IF(DAYOFWEEK(DeliveryDate) = '2', value, NULL)) AS 'Mon',
SUM(IF(DAYOFWEEK(DeliveryDate) = '3', value, NULL)) AS 'Tue',
SUM(IF(DAYOFWEEK(DeliveryDate) = '4', value, NULL)) AS 'Wed',
SUM(IF(DAYOFWEEK(DeliveryDate) = '5', value, NULL)) AS 'Thu',
SUM(IF(DAYOFWEEK(DeliveryDate) = '6', value, NULL)) AS 'Fri',
SUM(IF(DAYOFWEEK(DeliveryDate) = '7', value, NULL)) AS 'Sat',
SUM(IF(DAYOFWEEK(DeliveryDate) = '1', value, NULL)) AS 'Sun',
SUM(IF(DeliveryDate > DATE_ADD(CURDATE(),INTERVAL 7 DAY), value, NULL)) AS 'Future'
FROM view1
GROUP BY PartNum;
Behavoiur as designed
http://dev.mysql.com/doc/refman/5.1/en/create-view.html
You have to build a view from your subquery and use this.