I'm new to sql servers, I have a table as follows
**Emp_name | year | rank **
emp1 2010 1
emp1 2011 2
emp1 2012 3
emp2 2012 1
emp2 2013 2
emp3 2009 3
emp2 2010 4
emp3 2011 5
Emp_name column has duplicate values, I want a query that will return following result,
**Emp_name | year | rank **
emp1 2010 1
null (emp1) 2011 2
null (emp1) 2012 3
emp2 2012 1
null (emp2) 2013 2
emp3 2009 3
null (emp2) 2010 4
null (emp3) 2011 5
Only 1 of the values from the duplicate values(Emp_name column should be seen and the rest as null or as a blank space.
try this:
CREATE TABLE Table1
(Emp_name varchar(4), year int, rank int)
;
INSERT INTO Table1
(Emp_name, year, rank)
VALUES
('emp1', 2010, 1),
('emp1', 2011, 2),
('emp1', 2012, 3),
('emp2', 2012, 1),
('emp2', 2013, 2),
('emp3', 2009, 3),
('emp2', 2010, 4),
('emp3', 2011, 5)
;
select
CASE WHEN rn=1 then EMP_NAME else null end EMP_NAME,
year,rank
from
(
select *,ROW_NUMBER() over (partition by emp_name order by (select 0)) as rn from Table1
) a
Related
If I have a table below:
company | year |quarter| revenue
A 2019 1 200
A 2019 3 100
B 2019 2 80
B 2019 4 40
How can I get the result displayed as:
year |quarter| company |revenue
2019 1 A
2019 2 A
2019 3 A
2019 4 A
2019 1 B
... ... B
A cross join should do
with cte as
(
select distinct company,year from t
)
select cte.year,s.qtr,cte.company
from cte
cross join (select 1 as qtr union select 2 union select 3 union select 4) s
order by cte.company,s.qtr;
I have the following table:
t1:
id item
--------------------------
XR-2017-432 car
XR-2019-736 car
BC-2017-847 motorbike
XR-2017-937 car
BC-2020-758 motorbike
GK-2019-823 boat
GK-2017-928 boat
XR-2018-438 car
And I want to count the number of occurences of each year.
The answer of the query should be this:
result:
year count
-------------------
2017 4
2018 1
2019 2
2020 1
How can I do this with a MySQL query?
Consider:
select substr(id, 4, 4) yr, count(*) cnt
from mytable
group by yr
order by yr
substr(id, 4, 4) extracts the relevant part of the string (4 characters starting from the 4th character in the string), which you can then use for grouping).
Demo on DB Fiddle:
yr | cnt
:--- | --:
2017 | 4
2018 | 1
2019 | 2
2020 | 1
Try this with substring_index.
select
substring_index(substring_index(mt, "-", -2), "-", 1) as year,
count(*) as count
from yourTable
group by
year
I have a query which does not output the result I want. I spent several days on this, but I did not find a solution.
My Code
SELECT *, IFNULL(type, 'N/A') AS groupField, IFNULL(type, 'N/A') AS displayField, `pmonth`, `pyear`, count(prj.code) as projects_num
FROM `tblProjecats` `prj`
LEFT JOIN ( select cda, pyear, pmonth, sum(venituri) venituri, sum(cheltuieli) cheltuieli, sum(if(cont3 between 500 and 550,cheltuieli,0)) cheltuieliD, sum(if(cont3 > 550,cheltuieli,0)) cheltuieliI from buffer_cda group by pyear, pmonth, cda ) cda ON `cda`.`cda`=`prj`.`code`
-- more simple left jons --
WHERE (concat(pyear,lpad(pmonth,2,0)) BETWEEN 201811 AND 201911)
GROUP BY `type`, concat_ws('', `cda`.`pyear`, lpad(cda.pmonth, 2, '0'))
ORDER BY `type` ASC, `pyear` ASC, `pmonth` ASC, `cda` ASC
Table tblProjects
code type
66666 N/A
66667 Custom
66668 Simple
66669 Simple
66610 N/A
66611 Custom
66612 N/A
Table buffer_cda (with project Type joined for easier visualization)
cda pmonth pyear type cheltuieliD
66666 1 2019 N/A 1
66667 1 2019 Custom 10
66668 1 2019 Simple 100
66669 12 2018 Simple 200
66610 12 2018 N/A 2
66611 12 2018 Custom 20
66612 12 2018 N/A 3
66612 12 2018 N/A 4
Expected result
Type pmonth pyear count_prj cheltuieliD
N/A 12 2018 2 9
N/A 1 2019 1 1
Custom 12 2018 1 20
Custom 1 2019 1 10
Simple 12 2018 1 200
Simple 1 2019 1 100
Actual result
Type pmonth pyear count_prj cheltuieliD
N/A 12 2018 2 7
N/A 1 2019 8 1
Custom 12 2018 1 20
Custom 1 2019 3 10
Simple 12 2018 1 200
Simple 1 2019 1 100
I am doing something wrong with groupings but I do not know what. In other cases I have a duplicate Type results with cheltuieliD= 2 and cheltuieliD= 7 (instead of one type with cheltuieliD=9)
Next step on this would be calculating the cheltuieliD indicator on each project type, on Period Groups (month/Year) and then a grand total. Is this possible with a single query?
Chnge your groupby sequence with cda, pyear, pmonth...
If you just want to return project count every month then remove cda frim groupby clause...
If you could explain what logical operation you want to perform we can help.
Your data does not seem to be representative of your problem but given the sample data provided I would code like this
drop table if exists tblprojects,buffer_cda;
create table tblProjects
(code int, type varchar(20));
insert into tblprojects values
(66666 , 'N/A'),
(66667 , 'Custom'),
(66668 , 'Simple'),
(66669 , 'Simple'),
(66610 , 'N/A'),
(66611 , 'Custom'),
(66612 , 'N/A');
create Table buffer_cda
(cda int,pmonth int, pyear int, cheltuieliD int);
insert into buffer_cda values
(66666 , 1 ,2019 , 1),
(66667 , 1 ,2019 , 10),
(66668 , 1 ,2019 , 100),
(66669 , 12 ,2018 , 200),
(66610 , 12 ,2018 , 2),
(66611 , 12 ,2018 , 20),
(66612 , 12 ,2018 , 3),
(66612 , 12 ,2018 , 4);
select type,pmonth,pyear,count(type),sum(cheltuieliD)
from tblprojects tp
join buffer_cda bc on bc.cda = tp.code
group by type,pyear,pmonth;
+--------+--------+-------+-------------+------------------+
| type | pmonth | pyear | count(type) | sum(cheltuieliD) |
+--------+--------+-------+-------------+------------------+
| Custom | 12 | 2018 | 1 | 20 |
| Custom | 1 | 2019 | 1 | 10 |
| N/A | 12 | 2018 | 3 | 9 |
| N/A | 1 | 2019 | 1 | 1 |
| Simple | 12 | 2018 | 1 | 200 |
| Simple | 1 | 2019 | 1 | 100 |
+--------+--------+-------+-------------+------------------+
I found the correct way!
Thank you all for your responses!
I had to swap joining buffer_cda on projects to projects joining to buffer_cda.
More on, I had to eliminate other joins.
Bellow my answer, written for codeigniter!
$this->db->select("*,IFNULL(".$groupField.", 'N/A') AS groupField, IFNULL(".$displayField.", 'N/A') AS displayField, luna,anul,
count(DISTINCT prj.code) as projects_num,
sum(if(cont3 between 500 and 550,cheltuieli,0)) AS cheltuieliD,
sum(if(cont3 > 550,cheltuieli,0)) cheltuieliI,
sum(if(cont3 between 500 and 550,cheltuieli,0))/count(DISTINCT prj.code) AS cheltuieliDAvg,
sum(if(cont3 > 550,cheltuieli,0))/count(DISTINCT prj.code) cheltuieliIAvg
");
$this->db->from('buffer_cda cda');
$this->db->join('(
select * from tblProjects ) prj', 'cda.cda=prj.code', 'LEFT');
I also grouped by type, pyear, pmonth.
Have to get this result for the following problem in mysql
For example this table contains, values for columns month, amt1, amt2, amt3;
if amt1 has values then amt2 and amt3 will be null and similarly for amt2 and amt3.
All columns are VARCHAR
But there is a possibility of first row or similar rows for value in month column containing amt1 without null
might be
equal for the first or similar rows for value in month column containing amt2 without null
and so on....
How to get a result like this
-------------------------------------------------------------------------------------
month | amt1 | amt2 | amt3
-------------------------------------------------------------------------------------
january - 2013 1000 null null
january - 2013 null 2000 null
February - 2013 1000 null null
January - 2013 null 2000 null
February - 2013 null 2000 null
March - 2013 null null 3000
January - 2013 null null 3000
January - 2013 20 null null
February- 2013 null 30 null
March- 2013 null null 40
March- 2013 null 5000 null
March- 2013 null 50 null
So the result table should sum-up the available amounts in that particular month, if null exists it should return 0
-------------------------------------------------------------------------------------
month | amt1 | amt2 | amt3
-------------------------------------------------------------------------------------
January - 2013 1020 2000 0
February - 2913 1000 2030 3000
March - 2013 0 5050 3040
-------------------------------------------------------------------------------------
Use a combination of SUM, SUBSTRING and COALESCE and LOCATE function
A simple and fast query with the advice of David Wallace is as follows.
SELECT
month,
COALESCE(SUM(amt1),0) as amt1,
COALESCE(SUM(amt2),0) as amt2,
COALESCE(SUM(amt3),0) as amt3
From
Table1
GROUP BY
REPLACE(month,' ', '');
working demo at http://sqlfiddle.com/#!2/35547/27
VARCHAR to number conversion should be implicit. But if needed you can explicitly cast as CAST(amt, DECIMAL(p, s)). Why don't you try a simple aggregation like this,
SELECT
month,
SUM (amt1),
SUM (amt2),
SUM (amt3)
From Table
Group By month
I know this is a little complicated and I could accomplish this using other methods, but please bear with me.
I am trying to join a table filled with dates with a table filled with events so I can show dates which have no events. I wrote a QUERY that handles this fine, but if I have more than one event on a particular date I can't seem to join multiple records. I have tried all variations of joins.
Please see my problem here
SQL Code
SELECT #RowNumber := #RowNumber + 1 AS DayNumber, D.Date, L.LessonID, L.Title
FROM dates D
JOIN (SELECT #RowNumber:= 0) R
LEFT JOIN lessons L ON L.DayNumber = (#RowNumber+1)
WHERE D.Date IN ('2012-01-01','2012-01-03','2012-01-05','2012-01-10')
ORDER BY DayNumber ASC LIMIT 0, 50
Table Schema
CREATE TABLE IF NOT EXISTS `dates` (
`DateID` int(11) NOT NULL AUTO_INCREMENT,
`Date` date NOT NULL,
`TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`DateID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `dates` (`DateID`, `Date`, `TimeStamp`) VALUES
(1, '2012-01-01', '2013-02-16 17:38:07'),
(2, '2012-01-02', '2013-02-16 17:38:07'),
(3, '2012-01-03', '2013-02-16 17:38:07'),
(4, '2012-01-04', '2013-02-16 17:38:07'),
(5, '2012-01-05', '2013-02-16 17:38:07'),
(6, '2012-01-06', '2013-02-16 17:38:07'),
(7, '2012-01-07', '2013-02-16 17:38:07'),
(8, '2012-01-08', '2013-02-16 17:38:07'),
(9, '2012-01-09', '2013-02-16 17:38:07'),
(10, '2012-01-10', '2013-02-16 17:38:07');
CREATE TABLE IF NOT EXISTS `lessons` (
`LessonID` int(11) NOT NULL AUTO_INCREMENT,
`DayNumber` int(11) NOT NULL DEFAULT '0',
`Title` varchar(1024) NOT NULL,
`TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`LessonID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `lessons` (`LessonID`, `DayNumber`, `Title`, `TimeStamp`) VALUES
(1, 1, 'asdfasdf', '2012-01-01 18:03:21'),
(2, 1, 'qwerqwer', '2012-01-05 18:03:21'),
(3, 3, '12341234', '2012-01-05 18:03:34');
Results
Right now this returns this:
DAYNUMBER DATE LESSONID TITLE
1 January, 01 2012 00:00:00+0000 1 asdfasdf
2 January, 03 2012 00:00:00+0000 (null) (null)
3 January, 05 2012 00:00:00+0000 3 12341234
4 January, 10 2012 00:00:00+0000 (null) (null)
But I would like it to return this (note the second row on DayNumber 1 with the title "qwerqwer"):
DAYNUMBER DATE LESSONID TITLE
1 January, 01 2012 00:00:00+0000 1 asdfasdf
1 January, 01 2012 00:00:00+0000 1 qwerqwer
2 January, 03 2012 00:00:00+0000 (null) (null)
3 January, 05 2012 00:00:00+0000 3 12341234
4 January, 10 2012 00:00:00+0000 (null) (null)
If I'm understanding your question correctly, you could do something like this:
SELECT T.DayNumber,
T.Date,
L.LessonId,
L.Title
FROM (
SELECT #RowNumber := #RowNumber + 1 AS DayNumber,
D.Date
FROM dates D
JOIN (SELECT #RowNumber:= 0) R
WHERE D.Date IN ('2012-01-01','2012-01-03','2012-01-05','2012-01-10')
) T LEFT JOIN Lessons L ON
T.DayNumber = L.DayNumber
ORDER BY T.DayNumber ASC LIMIT 0, 50
Here is the updated Fiddle.
And here are the results:
DAYNUMBER DATE LESSONID TITLE
1 January, 01 2012 00:00:00+0000 1 asdfasdf
1 January, 01 2012 00:00:00+0000 2 qwerqwer
2 January, 03 2012 00:00:00+0000 (null) (null)
3 January, 05 2012 00:00:00+0000 3 12341234
4 January, 10 2012 00:00:00+0000 (null) (null)
BTW -- In your results above, you have Lesson Id 1 for your 2nd result -- I assume you meant Lesson Id 2 as in the above results.