How to dynamic pivot mysql table? - mysql

Hi I've got the following mysql table:
I need to pivot these datas to look like the following:
The scadenza is not always the same and can change therefore I believe I need to create the pivot table dynamically, This is the stored procedure I've tried:
BEGIN
SELECT
GROUP_CONCAT(
CONCAT("MAX(IF(scadenza='", scadenza, "',importo ,'')) AS '", scadenza, "'"), "
"
)INTO #answers
FROM (
SELECT DISTINCT scadenza,
importo
FROM ripartizione_rate
) A;
SET #query :=
CONCAT(
'SELECT DISTINCT condomino, anagrafica,', #answers,
'FROM ripartizione_rate
GROUP BY condomino, anagrafica'
);
PREPARE statement FROM #query;
EXECUTE statement;
END
The result I get is very close but I get the date repeated as you can see in the image below:
Can please anyboby halp me to fix this problem? Many thanks for your help
This is the dump text for the table
INSERT INTO `ripartizione_rate` (`id`, `preventivo`, `piano_rateale`, `condomino`, `anagrafica`, `immobile`, `descrizione`, `scadenza`, `stato_pagamento`, `importo`, `importo_pagato`, `importo_residuo`) VALUES
(1, 1, 1, 19, 11, 3, 'Rata Num.1', '2021-01-01', 0, '208.38', '0.00', '0.00'),
(2, 1, 1, 12, 15, 3, 'Rata Num.1', '2021-01-01', 0, '208.38', '0.00', '0.00'),
(3, 1, 1, 10, 15, 5, 'Rata Num.1', '2021-01-01', 0, '500.10', '0.00', '0.00'),
(4, 1, 1, 20, 17, 3, 'Rata Num.1', '2021-01-01', 0, '83.35', '0.00', '0.00'),
(5, 1, 1, 19, 11, 3, 'Rata Num.2', '2021-05-01', 0, '208.31', '0.00', '0.00'),
(6, 1, 1, 12, 15, 3, 'Rata Num.2', '2021-05-01', 0, '208.31', '0.00', '0.00'),
(7, 1, 1, 10, 15, 5, 'Rata Num.2', '2021-05-01', 0, '499.95', '0.00', '0.00'),
(8, 1, 1, 20, 17, 3, 'Rata Num.2', '2021-05-01', 0, '83.33', '0.00', '0.00'),
(9, 1, 1, 19, 11, 3, 'Rata Num.3', '2021-09-01', 0, '208.31', '0.00', '0.00'),
(10, 1, 1, 12, 15, 3, 'Rata Num.3', '2021-09-01', 0, '208.31', '0.00', '0.00'),
(11, 1, 1, 10, 15, 5, 'Rata Num.3', '2021-09-01', 0, '499.95', '0.00', '0.00'),
(12, 1, 1, 20, 17, 3, 'Rata Num.3', '2021-09-01', 0, '83.33', '0.00', '0.00');

The subquery part here:
SELECT
GROUP_CONCAT(
CONCAT("MAX(IF(scadenza='", scadenza, "',importo ,'')) AS '", scadenza, "'"), "
"
)INTO #answers
FROM (
SELECT DISTINCT scadenza, <----
importo <---- this subquery
FROM ripartizione_rate <----
) A
returns the following result:
+------------+---------+
| scadenza | importo |
+------------+---------+
| 2021-01-01 | 208.38 |
| 2021-01-01 | 500.10 |
| 2021-01-01 | 83.35 |
| 2021-05-01 | 208.31 |
| 2021-05-01 | 499.95 |
| 2021-05-01 | 83.33 |
| 2021-09-01 | 208.31 |
| 2021-09-01 | 499.95 |
| 2021-09-01 | 83.33 |
+------------+---------+
Each date returns 3 rows due to the DISTINCT combination of scadenza, importo. If you run SELECT #answers; after the variable being assigned then you'll get:
SELECT #answers;
+-------------------------------------------------------------+
| #answers |
+-------------------------------------------------------------+
| MAX(IF(scadenza='2021-01-01',importo ,'')) AS '2021-01-01' |
| ,MAX(IF(scadenza='2021-01-01',importo ,'')) AS '2021-01-01' |
| ,MAX(IF(scadenza='2021-01-01',importo ,'')) AS '2021-01-01' |
| ,MAX(IF(scadenza='2021-05-01',importo ,'')) AS '2021-05-01' |
| ,MAX(IF(scadenza='2021-05-01',importo ,'')) AS '2021-05-01' |
| ,MAX(IF(scadenza='2021-05-01',importo ,'')) AS '2021-05-01' |
| ,MAX(IF(scadenza='2021-09-01',importo ,'')) AS '2021-09-01' |
| ,MAX(IF(scadenza='2021-09-01',importo ,'')) AS '2021-09-01' |
| ,MAX(IF(scadenza='2021-09-01',importo ,'')) AS '2021-09-01' |
+-------------------------------------------------------------+
Whereas what you really want is just 3 distinctive dates instead of 3x3 distinctive dates. Therefore, the fix is quite simple really, you just need to remove the column importo from the subquery:
SELECT
GROUP_CONCAT(
CONCAT("MAX(IF(scadenza='", scadenza, "',importo ,'')) AS '", scadenza, "'"), "") INTO #answers
FROM (SELECT DISTINCT scadenza
FROM ripartizione_rate
) A;
SELECT #answers;
SET #query :=
CONCAT(
'SELECT DISTINCT condomino, anagrafica,', #answers2,
'FROM ripartizione_rate
GROUP BY condomino, anagrafica
ORDER BY condomino, anagrafica'
);
SELECT #query;
PREPARE statement FROM #query;
EXECUTE statement;
Demo fiddle

Related

MySQL query to show data separated by comma with group by different columns

I have a MySQL table where I have stored all of users searches. So the table looks something like this
CREATE TABLE `users_search_activity` (
`ID` bigint(20) UNSIGNED NOT NULL,
`user_id` int(11) NOT NULL,
`country_id` int(11) NOT NULL,
`search_keywords` text COLLATE utf8mb4_unicode_ci NOT NULL,
`date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `users_search_activity`
--
INSERT INTO `users_search_activity` (`ID`, `user_id`, `country_id`, `search_keywords`, `date`) VALUES
(1, 132, 2, 'xavie', '2021-07-13 08:20:37'),
(2, 132, 6, 'xavier', '2021-07-13 08:21:38'),
(3, 132, 5, 'xavier ins', '2021-07-13 08:21:39'),
(4, 132, 4, 'xavier ins', '2021-07-13 08:21:39'),
(5, 131, 9, 'xavier ins', '2021-07-13 08:22:12'),
(6, 132, 7, 'xavier ins', '2021-07-13 08:22:25'),
(7, 132, 8, 'xavier ins', '2021-07-13 09:24:43'),
(8, 132, 6, 'xavier ins', '2021-07-13 09:24:45'),
(9, 132, 4, 'xavier insa', '2021-07-13 09:24:47'),
(10, 131, 5, 'ins', '2021-07-13 09:24:54'),
(11, 132, 3, 'ins', '2021-07-13 09:24:54'),
(12, 132, 2, 'ins', '2021-07-13 09:24:58'),
(13, 132, 9, 'ins', '2021-07-13 09:24:59'),
(14, 132, 0, 'ins', '2021-07-13 09:25:00'),
(15, 132, 0, 'ins', '2021-07-13 09:25:02'),
(16, 132, 0, 'inst', '2021-07-13 09:58:20'),
(17, 132, 0, 'inst', '2021-07-04 09:58:25'),
(18, 132, 0, 'inst', '2021-07-07 09:58:25'),
(19, 132, 0, 'inst', '2021-07-11 09:58:26'),
(20, 1, 12, 'University Business Academy in Novi Sad', '2021-07-14 10:16:33');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users_search_activity`
--
ALTER TABLE `users_search_activity`
ADD PRIMARY KEY (`ID`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `users_search_activity`
--
ALTER TABLE `users_search_activity`
MODIFY `ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=20;
COMMIT;
Now I want to make some query from where I can get the data group by country_id and date.
So for that I have made my query like this
WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY country_id, DATE(date) ORDER BY ID) rn, COUNT(*) OVER (PARTITION BY country_id, DATE(date)) cnt FROM users_search_activity ) SELECT ID, cnt AS count, search_keywords, user_id, country_id, DATE(date) as date FROM cte WHERE rn = 1;
Here its working fine except the search_keywords. It is only showing single search_keywords. I want to show them all one by one separated by comma for the given date and country_id.
So can someone tell me how to do that? Any help or suggestions would be really appreciable.
Thanks,
The output should be something like this
count user_id country_id date search_keywords
1 132 4 2021-07-13 xavier ins, xavier insa
you can use group_concat
WITH cte AS (
SELECT *,DATE(date),ROW_NUMBER() OVER (PARTITION BY country_id, DATE(date) ORDER BY ID) rn,
COUNT(*) OVER (PARTITION BY country_id, DATE(date)) cnt
FROM users_search_activity
)
,tab2 as (
select t1.country_id,
date(date) dat,
group_concat(t1.search_keywords)
from cte t1
group by t1.country_id,
date(date)
)
SELECT *
FROM cte t1,
tab2 t2
WHERE t1.rn = 1
and t1.country_id = t2.country_id
and DATE(t1.date) = t2.dat
;
update at 2021/8/3
5.7 also has group_concat,you just need to deal with row_number.
select t1.country_id,
date(date) dat,
group_concat(t1.search_keywords),
max(case when t1.row_number = 1 then t1.user_id else null end) user_id
from (
select t1.*,
#rn := case when #temp1 is null then 1
when #temp1 = t1.country_id and #temp2 = DATE(date) then 0
else 1
end row_number,
#temp1:= t1.country_id,
#temp2:= DATE(date)
from users_search_activity t1,(select #rn:=0, #temp1:='', #temp2:='') t2
order by country_id, DATE(date), t1.id
) t1
group by t1.country_id,
date(date)
;
First of all thanks for providing such detail information in text format. Your question deserves upvote for that.
You don't need any ranking function like row_number() or cte. Simple group by with group_concat() is enough.
Query:
SELECT COUNT(*) OVER (PARTITION BY country_id, DATE(date)) AS count,
user_id, country_id, DATE(date) as date, group_concat(search_keywords) FROM users_search_activity
group by user_id,country_id,DATE(date)
Output:
|count | user_id | country_id | date | group_concat(search_keywords)
|----: | ------: | ---------: | :--------- | :--------------------------------------
| 1 | 132 | 0 | 2021-07-04 | inst
| 1 | 132 | 0 | 2021-07-07 | inst
| 1 | 132 | 0 | 2021-07-11 | inst
| 1 | 132 | 0 | 2021-07-13 | inst,ins,ins
| 1 | 132 | 2 | 2021-07-13 | xavie,ins
| 1 | 132 | 3 | 2021-07-13 | ins
| 1 | 132 | 4 | 2021-07-13 | xavier insa,xavier ins
| 2 | 131 | 5 | 2021-07-13 | ins
| 2 | 132 | 5 | 2021-07-13 | xavier ins
| 1 | 132 | 6 | 2021-07-13 | xavier ins,xavier
| 1 | 132 | 7 | 2021-07-13 | xavier ins
| 1 | 132 | 8 | 2021-07-13 | xavier ins
| 2 | 131 | 9 | 2021-07-13 | xavier ins
| 2 | 132 | 9 | 2021-07-13 | ins
| 1 | 1 | 12 | 2021-07-14 | University Business Academy in Novi Sad
db<>fiddle here

how to sum total and use it in each row in mysql

hi I'm trying since yesterday to get the sum of each previous row and use it in the next row but I got the wrong results, my SQL statement is:
SELECT `RegDate`,`RegdM2`,`RegdD2`,
(#s := #s + `RegdM2`-`RegdD2`) as xresult
from tblregs2 b
cross join (select #s := 0) c
INNER JOIN tblregs1 a ON b.RegRef = a.RegRef
WHERE `RegdAccID`=32
ORDER BY RegDate
tblregs1 definition is:
CREATE TABLE `tblregs1` (
`RegID` bigint(20) NOT NULL,
`RegRef` bigint(20) NOT NULL,
`RegCode` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`RegDate` date NOT NULL,
`RegCurr` int(11) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tblregs1` (`RegID`, `RegRef`, `RegCode`, `RegDate`, `RegCurr`,
`RegDetails`, `RegType`, `RegStatus`) VALUES
(1, 202010011140192, '', '2020-10-01', 1),
(2, 202010011141252, '', '2020-10-01', 1),
(3, 202010011141562, '', '2020-10-01', 1),
(4, 202010011143242, '', '2020-10-02', 0),
(5, 202010010103422, '', '2020-10-01', 1),
(6, 202010020836472, '', '2020-10-01', 0),
(7, 202010030101142, '', '2020-10-02', 0),
(8, 202010030101272, '', '2020-10-02', 0),
(9, 202010030101392, '', '2020-10-02', 0),
(10, 202010030101522, '', '2020-10-02', 0),
(11, 202010030102112, '', '2020-10-02', 0),
(12, 202010030153562, '', '2020-10-03', 1),
(14, 202010030158322, '', '2020-10-03', 1),
(15, 202010030431432, '', '2020-10-02', 0),
(16, 202010030439122, '', '2020-10-01', 1),
(17, 202010030512263, '', '2020-10-01', 1),
(18, 202010030515133, '', '2020-10-03', 2),
(19, 202010041255541, '', '2020-10-02', 1);
tblregs2 definition is:
CREATE TABLE `tblregs2` (
`RegdID` bigint(20) NOT NULL,
`RegRef` bigint(20) NOT NULL,
`RegdM1` double NOT NULL DEFAULT '0',
`RegdD1` double NOT NULL DEFAULT '0',
`RegdAccID` int(11) NOT NULL,
`RegdDetails` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`RegdCurrPrice` double NOT NULL DEFAULT '0',
`RegdM2` double NOT NULL DEFAULT '0',
`RegdD2` double NOT NULL DEFAULT '0',
`RecStatus` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Normal',
`RegdNo` tinyint(4) NOT NULL,
`RegdMtbkRaseed` double NOT NULL DEFAULT '0',
`RegdMtbkFark` double NOT NULL DEFAULT '0',
`RegdMtbkStatus` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`RegdMtbkNotes` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tblregs2` (`RegdID`, `RegRef`, `RegdM1`, `RegdD1`,
`RegdAccID`, `RegdDetails`, `RegdCurrPrice`, `RegdM2`, `RegdD2`,
`RecStatus`, `RegdNo`, `RegdMtbkRaseed`, `RegdMtbkFark`, `RegdMtbkStatus`,
`RegdMtbkNotes`) VALUES
(1, 202010011140192, 1000, 0, 916, 'Des1', 1, 1000, 0, 'Normal', 0, 0, 0,
NULL, NULL),
(4, 202010011141252, 0, 10000, 32, 'Des1', 1, 0, 10000, 'Normal', 2, 0, 0,
NULL, NULL),
(13, 202010011143242, 1680, 0, 32, 'Des1', 1, 1680, 0, 'Normal', 3, -8320,
0, 'no', 'no'),
(14, 202010011143242, 0, 1680, 15, 'Des1', 1, 0, 1680, 'Normal', 4, 0, 0,
NULL, NULL),
(16, 202010011143242, 0, 10, 32, 'Des1', 1, 0, 10, 'Normal', 6, 0, 0,
NULL, NULL),
(17, 202010011143242, 15, 0, 32, 'Des1', 1, 15, 0, 'Normal', 7, -8315, 0,
'', '-8315'),
(19, 202010011143242, 450000, 0, 32, 'Des1', 1235, 364.37, 0, 'Normal', 9,
0, 0, '', ''),
(20, 202010011143242, 0, 450000, 306, 'Des1', 1, 0, 450000, 'Normal', 10,
0, 0, NULL, NULL),
(33, 202010020836472, 0, 0, 916, '', 0, 0, 0, 'Normal', 9, 0, 0, NULL,
NULL),
(34, 202010020836472, 0, 0, 86, '', 0, 0, 0, 'Normal', 10, 0, 0, NULL,
NULL),
(35, 202010030153562, 1400, 0, 32, 'Des1', 32, 1400, 0, 'Normal', 0,
-6550.63, 0, '', '12'),
(36, 202010030153562, 0, 1400, 55, 'Des1', 55, 0, 1400, 'Normal', 0, 0, 0,
NULL, NULL),
(38, 202010030158322, 0, 7000, 32, 'Des1', 1, 0, 7000, 'Normal', 2, 0, 0,
NULL, NULL),
(64, 202010041255541, 0, 4500, 32, 'Des1', 1, 0, 4500, 'Normal', 2, 0, 0,
NULL, NULL),
(65, 202010041255541, 10, 0, 33, 'Des1', 1, 10, 0, 'Normal', 3, 0, 0,
NULL, NULL),
(66, 202010041255541, 0, 10, 45, 'Des1', 1, 0, 10, 'Normal', 4, 0, 0,
NULL, NULL);
example of my data for the specified user is:
+-------+-----------+--------+-----------+--------+--------+
| RegID | RegDate | RegdID | RegdAccID | RegdM2 | RegdD2 |
+-------+-----------+--------+-----------+--------+--------+
| 2 | 10/1/2020 | 4 | 32 | 0 | 10000 |
+-------+-----------+--------+-----------+--------+--------+
| 4 | 10/2/2020 | 13 | 32 | 1680 | 0 |
+-------+-----------+--------+-----------+--------+--------+
| 4 | 10/2/2020 | 16 | 32 | 0 | 10 |
+-------+-----------+--------+-----------+--------+--------+
| 4 | 10/2/2020 | 17 | 32 | 15 | 0 |
+-------+-----------+--------+-----------+--------+--------+
| 4 | 10/2/2020 | 19 | 32 | 364.37 | 0 |
+-------+-----------+--------+-----------+--------+--------+
| 12 | 10/3/2020 | 35 | 32 | 1400 | 0 |
+-------+-----------+--------+-----------+--------+--------+
| 14 | 10/3/2020 | 38 | 32 | 0 | 7000 |
+-------+-----------+--------+-----------+--------+--------+
| 19 | 10/2/2020 | 64 | 32 | 0 | 4500 |
+-------+-----------+--------+-----------+--------+--------+
this is the result that gives me:
+-----------+--------+--------+--------+-----------+
| RegDate | RegdID | RegdM2 | RegdD2 | Result |
+-----------+--------+--------+--------+-----------+
| 10/1/2020 | 4 | 0 | 10000 | -10000 |
+-----------+--------+--------+--------+-----------+
| 10/2/2020 | 13 | 1680 | 0 | -8320 |
+-----------+--------+--------+--------+-----------+
| 10/2/2020 | 16 | 0 | 10 | -8330 |
+-----------+--------+--------+--------+-----------+
| 10/2/2020 | 17 | 15 | 0 | -8315 |
+-----------+--------+--------+--------+-----------+
| 10/2/2020 | 19 | 364.37 | 0 | -7950.63 |
+-----------+--------+--------+--------+-----------+
| 10/2/2020 | 64 | 0 | 4500 | -18050.63 |
+-----------+--------+--------+--------+-----------+
| 10/3/2020 | 35 | 1400 | 0 | -6550.63 |
+-----------+--------+--------+--------+-----------+
| 10/3/2020 | 38 | 0 | 7000 | -13550.63 |
+-----------+--------+--------+--------+-----------+
now I added all the requested data, hope that will help
thanks, advanced
For 5.x version:
SELECT d.RegDate,
d.RegdID,
d.RegdM2,
d.RegdD2,
CAST(#s := #s + d.RegdM2-d.RegdD2 AS DECIMAL(10,2)) AS xresult
FROM (SELECT a.RegDate,
b.RegdM2,
b.RegdD2,
b.RegdID
FROM tblregs2 b
INNER JOIN tblregs1 a ON b.RegRef = a.RegRef
WHERE b.RegdAccID=32 ) d
CROSS JOIN (SELECT #s := 0) c
ORDER BY d.RegDate,
d.RegdID;
For 8+ version and one account:
SELECT a.RegDate,
b.RegdID,
b.RegdM2,
b.RegdD2,
CAST(SUM(b.RegdM2-b.RegdD2) OVER (PARTITION BY RegdAccID
ORDER BY a.RegDate, b.RegdID) AS DECIMAL(10,2)) xresult
FROM tblregs2 b
INNER JOIN tblregs1 a ON b.RegRef = a.RegRef
WHERE b.RegdAccID=32
ORDER BY a.RegDate,
b.RegdID;
For 8+ version and all accounts:
SELECT b.RegdAccID,
a.RegDate,
b.RegdID,
b.RegdM2,
b.RegdD2,
CAST(SUM(b.RegdM2-b.RegdD2) OVER (PARTITION BY RegdAccID
ORDER BY a.RegDate, b.RegdID) AS DECIMAL(10,2)) xresult
FROM tblregs2 b
INNER JOIN tblregs1 a ON b.RegRef = a.RegRef
ORDER BY b.RegdAccID,
a.RegDate,
b.RegdID;
fiddle

Extend given long MySQL query and get count of completed and not completed

When I write below MySQL query, it gives me correct output like mentioned after that I want to get completed and not completed count. I already tried but failed.
SQL Fiddle:
http://sqlfiddle.com/#!9/c8dab/1
Question:
How can I get completed and not completed count by extending below query?
Query:
SELECT keyworddefs.name as sprint,
SUM(CASE WHEN bugs.bug_status IN ('CLOSED', 'VERIFIED')
THEN bugs.cf1 + bugs.cf2
ELSE 0 END) completed,
SUM(bugs.cf1 + bugs.cf2) total,
(CASE WHEN SUM(CASE WHEN bugs.bug_status IN ('CLOSED', 'VERIFIED')
THEN bugs.cf1 + bugs.cf2
ELSE 0 END)=SUM(bugs.cf1 + bugs.cf2)
THEN 'Completed'
ELSE 'Not Completed' END) status
FROM bugs
JOIN keywords ON bugs.bug_id = keywords.bug_id
JOIN keyworddefs ON keyworddefs.id = keywords.keywordid
GROUP BY keywords.keywordid
ORDER BY keyworddefs.name DESC;
Output:
+--------+------------------------+--------------------+---------------+
| name | completed | total | status |
+--------+------------------------+--------------------+---------------+
| K2 | 14 | 14 | Completed |
| J2 | 16 | 24 | Not Completed |
| J1 | 0 | 5 | Not Completed |
+--------+------------------------+--------------------+---------------+
After extending query, expected output just:
+---------------+--------+
| status | count |
+------------------------+
| Completed | 1 |
| Not Completed | 2 |
+------------------------+
As Strawberry said, give it a derived table name.
Schema:
-- bugs table1 (master table) :
CREATE TABLE `bugs`
( `bug_id` int(11) NOT NULL,
`bug_date` date NOT NULL,
`cf1` int(11) NOT NULL,
`cf2` int(11) NOT NULL,
`bug_status` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `bugs` (`bug_id`, `bug_date`, `cf1`, `cf2`, `bug_status`) VALUES
(101, '2016-07-19', 3, 2, 'RESOLVED'),
(102, '2016-07-19', 2, 1, 'VERIFIED'),
(103, '2016-07-19', 2, 1, 'VERIFIED'),
(103, '2016-07-19', 2, 1, 'VERIFIED'),
(1363, '2016-07-19', 2, 1, 'VERIFIED'),
(1352, '2016-07-19', 2, 1, 'VERIFIED'),
(102, '2016-07-19', 2, 1, 'VERIFIED'),
(102, '2016-07-22', 2, 2, 'CLOSED'),
(103, '2016-07-22', 2, 2, 'CLOSED'),
(103, '2016-07-22', 2, 2, 'CLOSED'),
(102, '2016-07-19', 3, 2, 'NEW'),
(102, '2016-07-19', 2, 1, 'REOPENED'),
(102, '2016-07-19', 2, 1, 'CLOSED'),
(102, '2016-07-19', 2, 1, 'VERIFIED'),
(1363, '2016-07-19', 2, 1, 'VERIFIED'),
(1352, '2016-07-19', 2, 1, 'VERIFIED'),
(565, '2016-07-19', 2, 1, 'VERIFIED'),
(398, '2016-07-22', 2, 2, 'CLOSED'),
(565, '2016-07-22', 2, 2, 'CLOSED'),
(9872, '2016-07-22', 2, 2, 'CLOSED');
-- keywords table2 (having keyword ids):
CREATE TABLE `keywords`
( `bug_id` int(11) NOT NULL,
`keywordid` varchar(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `keywords` (`bug_id`, `keywordid`) VALUES
(101, '1'), (102, '2'), (103, '3'), (104, '4'), (105, '1'), (106, '1'), (107, '2'), (108, '3'), (109, '4');
-- keyworddefs table3 (having keyword names according to keywordid):
CREATE TABLE `keyworddefs`
( `id` int(11) NOT NULL,
`name` varchar(200) NOT NULL,
`description` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `keyworddefs` (`id`, `name`, `description`) VALUES
(1, 'J1', 'My J1 item'), (2, 'J2', 'My J2 item'), (3, 'K2', 'My K2 item'), (4, 'K2', 'My K2 item');
Your query:
SELECT keyworddefs.name as sprint,
SUM(CASE WHEN bugs.bug_status IN ('CLOSED', 'VERIFIED')
THEN bugs.cf1 + bugs.cf2
ELSE 0 END) completed_story_points,
SUM(bugs.cf1 + bugs.cf2) total_story_points,
(CASE WHEN SUM(CASE WHEN bugs.bug_status IN ('CLOSED', 'VERIFIED')
THEN bugs.cf1 + bugs.cf2
ELSE 0 END)=SUM(bugs.cf1 + bugs.cf2)
THEN 'Completed'
ELSE 'Not Completed' END) sprint_status
FROM bugs
JOIN keywords ON bugs.bug_id = keywords.bug_id
JOIN keyworddefs ON keyworddefs.id = keywords.keywordid
GROUP BY keywords.keywordid
ORDER BY keyworddefs.name DESC;
Your Output:
+--------+------------------------+--------------------+---------------+
| sprint | completed_story_points | total_story_points | sprint_status |
+--------+------------------------+--------------------+---------------+
| K2 | 14 | 14 | Completed |
| J2 | 16 | 24 | Not Completed |
| J1 | 0 | 5 | Not Completed |
+--------+------------------------+--------------------+---------------+
Wanted:
+---------------+--------+
| status | count |
+------------------------+
| Completed | 1 |
| Not Completed | 2 |
+------------------------+
Lazy approach (meaning, without much thought):
SELECT sprint_status,count(*) AS count
FROM
(
SELECT keyworddefs.name as sprint,
SUM(CASE WHEN bugs.bug_status IN ('CLOSED', 'VERIFIED')
THEN bugs.cf1 + bugs.cf2
ELSE 0 END) completed_story_points,
SUM(bugs.cf1 + bugs.cf2) total_story_points,
(CASE WHEN SUM(CASE WHEN bugs.bug_status IN ('CLOSED', 'VERIFIED')
THEN bugs.cf1 + bugs.cf2
ELSE 0 END)=SUM(bugs.cf1 + bugs.cf2)
THEN 'Completed'
ELSE 'Not Completed' END) sprint_status
FROM bugs
JOIN keywords ON bugs.bug_id = keywords.bug_id
JOIN keyworddefs ON keyworddefs.id = keywords.keywordid
GROUP BY keywords.keywordid
) xDerived
GROUP BY sprint_status
ORDER BY sprint_status;
Output:
+---------------+-------+
| sprint_status | count |
+---------------+-------+
| Completed | 1 |
| Not Completed | 2 |
+---------------+-------+
Order by whatever
Every derived table requires a name. The above wrapped chunk is one.
So we chose the name xDerived. It is not used by name thereafter (though it could have been). But it still needs a name or an Error will occur.

MySQL - GROUP BY clause recursively?

Under MySQL I can not group the three separate data columns via GROUP BY clause.
This sample contains four brands, each brand has 2 models and 4 versions of engines. I need to extract 4 vehicles the brand, the model and version of engines is different. A truly unique result in the 3 columns.
----------+--------+----------+
Brand | Model | Version |
----------+--------+----------+
Renault | Clio | Essence |
Citroen | C4 | GPL |
Ford | Fiesta | Gazole |
Peugeot | 206 | Electric |
----------+--------+----------+
This works 8/10.
SELECT brand, model, version
FROM cars WHERE version = (SELECT version FROM cars GROUP BY version ORDER BY RAND() LIMIT 1)
GROUP BY brand
An example of the table
CREATE TABLE IF NOT EXISTS `cars` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`brand` varchar(255) NOT NULL,
`model` varchar(255) NOT NULL,
`version` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ROW_FORMAT=COMPRESSED;
INSERT INTO `cars` (`id`, `brand`, `model`, `version`) VALUES
(1, 'Renault', 'Clio ', 'Essence'),
(2, 'Renault', 'Clio ', 'Gazole'),
(3, 'Renault', 'Clio ', 'GPL'),
(4, 'Renault', 'Clio ', 'Electric'),
(5, 'Renault', 'Modus', 'Essence'),
(6, 'Renault', 'Modus', 'Gazole'),
(7, 'Renault', 'Modus', 'GPL'),
(8, 'Renault', 'Modus', 'Electric'),
(9, 'Peugeot', '307', 'Essence'),
(10, 'Peugeot', '307', 'Gazole'),
(11, 'Peugeot', '307', 'GPL'),
(12, 'Peugeot', '307', 'Electric'),
(13, 'Peugeot', '206', 'Essence'),
(14, 'Peugeot', '206', 'Gazole'),
(15, 'Peugeot', '206', 'GPL'),
(16, 'Peugeot', '206', 'Electric'),
(17, 'Citroen', 'C4', 'Essence'),
(18, 'Citroen', 'C4', 'Gazole'),
(19, 'Citroen', 'C4', 'GPL'),
(20, 'Citroen', 'C4', 'Electric'),
(21, 'Citroen', 'C5', 'Essence'),
(22, 'Citroen', 'C5', 'Gazole'),
(23, 'Citroen', 'C5', 'GPL'),
(24, 'Citroen', 'C5', 'Electric'),
(25, 'Ford', 'Focus', 'Essence'),
(26, 'Ford', 'Focus', 'Gazole'),
(27, 'Ford', 'Focus', 'GPL'),
(28, 'Ford', 'Focus', 'Electric'),
(29, 'Ford', 'Fiesta', 'Essence'),
(30, 'Ford', 'Fiesta', 'Gazole'),
(31, 'Ford', 'Fiesta', 'GPL'),
(32, 'Ford', 'Fiesta', 'Electric');
If you need unique/distinct set of (Brand,Model,Version) add all three column name in GROUP BY clause like this:
SELECT brand, model, version FROM cars
WHERE version = (SELECT version FROM cars GROUP BY version ORDER BY RAND() LIMIT 1)
GROUP BY brand, model, version
Here is what I was offered, it is not optimized but it works.
If someone with a suggestion I'm interested.
CREATE TABLE IF NOT EXISTS temp AS
SELECT
tb1.id AS id1,
tb1.brand AS brand1,
tb1.model AS model1,
tb1.version AS version1,
tb2.id AS id2,
tb2.brand AS brand2,
tb2.model AS model2,
tb2.version AS version2,
tb3.id AS id3,
tb3.brand AS brand3,
tb3.model AS model3,
tb3.version AS version3,
tb4.id AS id4,
tb4.brand AS brand4,
tb4.model AS model4,
tb4.version AS version4
FROM `cars` AS tb1
INNER JOIN `cars` AS tb2
ON tb2.brand != tb1.brand
AND tb2.model != tb1.model
AND tb2.version != tb1.version
AND tb2.id > tb1.id
INNER JOIN `cars` AS tb3
ON tb3.brand != tb2.brand
AND tb3.model != tb2.model
AND tb3.version != tb2.version
AND tb3.id > tb2.id
AND tb3.brand != tb1.brand
AND tb3.model != tb1.model
AND tb3.version != tb1.version
AND tb3.id > tb1.id
INNER JOIN `cars` AS tb4
ON tb4.brand != tb3.brand
AND tb4.model != tb3.model
AND tb4.version != tb3.version
AND tb4.id > tb3.id
AND tb4.brand != tb2.brand
AND tb4.model != tb2.model
AND tb4.version != tb2.version
AND tb4.id > tb2.id
AND tb4.brand != tb1.brand
AND tb4.model != tb1.model
AND tb4.version != tb1.version
AND tb4.id > tb1.id
LIMIT 1
--------------
select * from sample
--------------
+-----+---------+--------+----------+-----+---------+--------+----------+-----+---------+--------+----------+-----+--------+--------+----------+
| id1 | brand1 | model1 | version1 | id2 | brand2 | model2 | version2 | id3 | brand3 | model3 | version3 | id4 | brand4 | model4 | version4 |
+-----+---------+--------+----------+-----+---------+--------+----------+-----+---------+--------+----------+-----+--------+--------+----------+
| 1 | Renault | Clio | Essence | 10 | Peugeot | 307 | Gazole | 19 | Citroen | C4 | GPL | 28 | Ford | Focus | Electric |
+-----+---------+--------+----------+-----+---------+--------+----------+-----+---------+--------+----------+-----+--------+--------+----------+
and get the result formatter
SELECT id1 AS id,
brand1 AS brand,
model1 AS model,
version1 AS version
FROM temp
UNION
SELECT id2 AS id,
brand2 AS brand,
model2 AS model,
version2 AS version
FROM temp
UNION
SELECT id3 AS id,
brand3 AS brand,
model3 AS model,
version3 AS version
FROM temp
UNION
SELECT id4 AS id,
brand4 AS brand,
model4 AS model,
version4 AS version
FROM temp
+----+---------+-------+----------+
| id | brand | model | version |
+----+---------+-------+----------+
| 1 | Renault | Clio | Essence |
| 10 | Peugeot | 307 | Gazole |
| 19 | Citroen | C4 | GPL |
| 28 | Ford | Focus | Electric |
+----+---------+-------+----------+

Mysql Grouping of Max field by month on a set of Fields

I would like to generate a SQL to list to display the maximum tally count based on enumerated group of values on a monthly basis. As this would be useful for analytics based algorithm in displaying the total impressions of a particular data type.
Please check my sample table:
CREATE TABLE IF NOT EXISTS `company_attendance_tally` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`start_date` datetime NOT NULL,
`sick_type` enum('VACATION','SICK','MATERNITY') COLLATE utf8_unicode_ci NOT NULL,
`leave_count` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `start_date` (`start_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=32 ;
--
-- Dumping data for table `company_attendance_tally`
--
INSERT INTO `company_attendance_tally` (`id`, `start_date`, `sick_type`, `leave_count`) VALUES
(1, '2013-03-01 16:58:44', 'VACATION', 5),
(2, '2013-03-15 10:44:35', 'SICK', 43),
(3, '2013-03-21 17:03:33', 'MATERNITY', 44),
(4, '2013-03-07 23:01:30', 'MATERNITY', 10),
(5, '2013-03-22 17:07:07', 'MATERNITY', 1),
(6, '2013-03-08 19:33:04', 'VACATION', 40),
(7, '2013-03-17 12:27:00', 'MATERNITY', 15),
(8, '2013-03-03 23:26:48', 'SICK', 11),
(9, '2013-03-05 02:16:37', 'MATERNITY', 41),
(10, '2013-03-20 12:04:28', 'MATERNITY', 18),
(11, '2013-03-18 02:10:00', 'MATERNITY', 1),
(12, '2013-03-03 09:47:02', 'MATERNITY', 19),
(13, '2013-03-22 10:17:52', 'MATERNITY', 25),
(14, '2013-03-03 19:41:52', 'VACATION', 10),
(15, '2013-03-02 19:28:41', 'SICK', 39),
(16, '2013-03-01 20:45:26', 'SICK', 42),
(17, '2013-03-26 23:52:16', 'MATERNITY', 29),
(18, '2013-03-29 14:10:58', 'SICK', 44),
(19, '2013-03-27 03:11:40', 'MATERNITY', 12),
(20, '2013-03-06 18:38:28', 'MATERNITY', 30),
(21, '2013-03-07 20:49:14', 'VACATION', 27),
(22, '2013-03-13 11:38:45', 'VACATION', 14),
(23, '2013-03-02 19:13:31', 'SICK', 2),
(24, '2013-03-01 10:08:18', 'SICK', 27),
(25, '2013-03-20 01:56:38', 'VACATION', 3),
(26, '2013-03-04 21:02:05', 'SICK', 7),
(27, '2013-03-17 00:47:17', 'MATERNITY', 36),
(28, '2013-03-04 08:12:56', 'VACATION', 5),
(29, '2013-03-18 08:50:57', 'SICK', 34),
(30, '2013-03-26 02:20:58', 'VACATION', 20),
(31, '2013-03-27 10:27:00', 'SICK', 21);
http://sqlfiddle.com/#!2/bbd1e3
I would like to display a similar output below based on the above scenario:
month| day | sick_type | leave_count |
-----------------------------------------------------
3| 08 | VACATION | 40
3| 29 | SICK | 29
3| 21 | MATERNITY | 44
and so on so forth...
4| ... | MATERNITY | ..
4| ... | SICK | ..
4| ... | VACATION | ..
5| ... | MATERNITY | ..
5| ... | SICK | ..
5| ... | VACATION | ..
If I understand correctly what you want you can do following by leveraging non-standard MySQL GROUP BY extension
SELECT MONTH(start_date) month,
DAYOFMONTH(start_date) day,
sick_type,
leave_count
FROM
(
SELECT start_date, sick_type, leave_count
FROM company_attendance_tally
WHERE start_date >= '2013-01-01'
AND start_date < '2014-01-01'
ORDER BY MONTH(start_date), sick_type, leave_count DESC
) q
GROUP BY MONTH(start_date), sick_type
Note: Month values alone (without a year values) in the resultset make sense only if you limit the resultset by one year boundaries (see WHERE clause).
Output:
| MONTH | DAY | SICK_TYPE | LEAVE_COUNT |
|-------|-----|-----------|-------------|
| 3 | 8 | VACATION | 40 |
| 3 | 29 | SICK | 44 |
| 3 | 21 | MATERNITY | 44 |
Here is SQLFiddle demo
Use this:
SELECT DAY( start_date ) AS d,
MONTH( start_date ) AS mon,
sick_type,
MAX( leave_count ) AS leave_count
FROM `company_attendance_tally`
GROUP BY mon, sick_type
If you want to do it 'by-the-book', consider the following...
SELECT x.*
FROM company_attendance_tally x
JOIN
( SELECT MONTH(start_date) start_month
, sick_type
, MAX(leave_count) max_leave_count
FROM company_attendance_tally
GROUP
BY MONTH(start_date)
, sick_type
) y
ON y.start_month = MONTH(x.start_date)
AND y.sick_type = x.sick_type
AND y.max_leave_count = x.leave_count;