Select n items starting with each alphabet from a-z in MySQL - mysql

I have tried asking this question previously but moderators closed the question citing it as not clear. Hope this time I make it clear.
I've a services table with up to 1000 services. The table has id & service_title column. So, I basically want to get 10 services each for each alphabet starting from A to Z. If there are fewer than 10 items starting with any particular alphabet than I want to get them all. Also I want them in alphabetical order if possible.
Here's my services table.
So my output table should look something like the one displayed below. For the sake of simplicity I've shown 2 services starting with each alphabet from A to J.
<table border="1">
<caption>Services</caption>
<thead>
<tr>
<th>id</th>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Auditing</td>
</tr>
<tr>
<td>2</td>
<td>Accounting</td>
</tr>
<tr>
<td>3</td>
<td>Brick laying</td>
</tr>
<tr>
<td>4</td>
<td>Builders</td>
</tr>
<tr>
<td>5</td>
<td>Carpet Cleaning</td>
</tr>
<tr>
<td>6</td>
<td>Carpenters</td>
</tr>
<tr>
<td>7</td>
<td>Demolition</td>
</tr>
<tr>
<td>8</td>
<td>Dog Walking</td>
</tr>
<tr>
<td>9</td>
<td>Electrician</td>
</tr>
<tr>
<td>10</td>
<td>Equipment Hire</td>
</tr>
<tr>
<td>11</td>
<td>Fencing & Gates</td>
</tr>
<tr>
<td>12</td>
<td>Fright Services</td>
</tr>
<tr>
<td>13</td>
<td>Gardeners</td>
</tr>
<tr>
<td>14</td>
<td>Gate keepers</td>
</tr>
<tr>
<td>15</td>
<td>Handyman</td>
</tr>
<tr>
<td>16</td>
<td>Health service</td>
</tr>
<tr>
<td>17</td>
<td>Interview Trainer</td>
</tr>
<tr>
<td>18</td>
<td>Iterpersonal Relationship Coach</td>
</tr>
<tr>
<td>19</td>
<td>Joinery Experts</td>
</tr>
<tr>
<td>20</td>
<td>Jacket Maker</td>
</tr>
</tbody>
</table>
Here's the code I've come up with till now
SELECT *
FROM (
SELECT id, service_title,
#count := IF(#value = service_title, #count + 1, 1) AS count
FROM services, (SELECT #count := 1, #value := NULL) a
WHERE services.service_title REGEXP '^[A-z]+$'
) a
WHERE a.count <= 10
Order by service_title
I've listed some services in my sample output table which are not listed in the sample items on the table image, please do not raise that as as issue as I can't display all items on the sample table image.

You may try below query with minor updates from your query -
SELECT *
FROM (SELECT id,
#count := IF(LEFT(#value, 1) = LEFT(service_title, 1), #count + 1, 1) AS cnt,
#value := service_title service_title
FROM services, (SELECT #count := 0, #value := 0) vars
WHERE services.service_title REGEXP '^[A-z]+'
ORDER BY service_title, id
) a
WHERE a.cnt <= 10
Order by service_title, id
Demo.

Related

get all records of same string under one title in laravel

I am currently getting records from multiple table by using join in laravel. But my issue is that the under the teacher name all records will show those have same teacher name others should be in next table like that
e.g
Teacher1 name
id name class subject
1 student1 8 chem
2 student2 9 phy
teacher2 name
3 student3 9 chem
4 student4 11 chem
teacher3 name
......
here is my laravel view
<table class="table">
<thead>
#foreach($students as $student)
<tr style="background-color: #e9e5e4;">
<td colspan="4">{{$student->teacher_name}}</td>
</tr>
<tr>
<th>Name</th>
<th>Class</th>
<th>Subject</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{$student->name }}</td>
<td>{{$student->class}} </td>
<td>{{$student->subject }} </td>
</tr>
#endforeach
</tbody>
</table>
but according to above code I have multiple issues like teacher name is repeating if duplicate entry found in database and I can't make teacher name unique because I need multiple entry of same name , secondly all records are showing under every teacher. my current output is like that
Teacher1 name
id name class subject
1 student1 8 chem
2 student2 9 phy
3 student3 9 chem
4 student4 11 chem
Teacher2 name
id name class subject
1 student1 8 chem
2 student2 9 phy
3 student3 9 chem
4 student4 11 chem
I assume that $students is collection. Then you can use the groupBy
method. You can rewrite your code like this:
#php
$index = 1;
#endphp
#foreach($students->groupBy('teacher_name') as $teacherName => $subStudents)
<h2>{{$teacherName}}</h2>
<table class="table">
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Class</th>
<th>Subject</th>
</tr>
</thead>
<tbody>
#foreach($subStudents as $student)
<tr>
<td>{{$index }}</td>
<td>{{$student->name }}</td>
<td>{{$student->class}} </td>
<td>{{$student->subject }} </td>
</tr>
#php
$index++;
#endphp
#endforeach
</tbody>
</table>
#endforeach
Let me know if that answer your question.

No alerts after incorrect after submitting

I have this class in Java: Tables(String eventName, List<StudentNameAndEstimate> list)
<table class="table">
<caption>My events</caption>
<tr>
<th>Name</th>
<th>Student</th>
<th>Progress</th>
</tr>
<tr th:for="">
<td th:text="${event.getEventName()}"></td>
???
</tr>
</table>
I don't understand how write list next in HTML.
I want to this table in result:
event1 student1 5
student2 4
student3 2
student4 5
...
studentN 5
event2 student1 5
...
It was only necessary to shove it into <th:block> </th:block>
<table class="table">
<caption>My events</caption>
<tr>
<th>Name</th>
<th>Student's Name</th>
<th>Estimate</th>
</tr>
<tr th:each="event:${events}">
<td th:text="${event.getEventName()}"></td>
<th:block th:each="stud:${event.getStudentEstimates()}">
<td th:text="${stud.getStudentName()}"></td>
<td th:text="${stud.getEstimate()}"></td>
</th:block>
</tr>
</table>

Using SQL read html data as XML

I have to read HTML table data as XML. But I am not able to get all the information as in my required format.
declare #xml xml='<body bgcolor="#FFFFFF">
<div id="Edit01" style="position:absolute; left:5px; top:4px; width:462px; height:196px; z-index:1">
<table width="462" border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="5" width="462">
<span class="auditnoteheader">Charges: </span>
</td>
</tr>
<tr>
<td colspan="5" width="462">
<span class="AuditNoteText">Submitted by ELSGH </span>
</td>
</tr>
<tr>
<td colspan="5" width="462">
<span class="AuditNoteText">Jul 20 2018 9:15PM Eastern Standard Time</span>
</td>
</tr>
<tr class="AuditNoteSubHeader">
<td width="8" />
<td width="230" valign="top">Charge</td>
<td width="110" valign="top">Old Charge Status</td>
<td width="114" valign="top">New Charge Status</td>
</tr>
<tr class="AuditNoteText">
<td width="8" />
<td width="230" valign="top">
<font color="009900">99214 OFFICE OUTPATIENT VISIT 25 MINUTES</font>
</td>
<td width="110" valign="top">
<font color="009900">Review</font>
</td>
<td width="114" valign="top">
<font color="009900">Submitted</font>
</td>
</tr>
<tr class="AuditNoteText">
<td width="8" />
<td width="230" valign="top">
<font color="009900">36415 COLLECTION VENOUS BLOOD</font>
</td>
<td width="110" valign="top">
<font color="009900">Review</font>
</td>
<td width="114" valign="top">
<font color="009900">Submitted</font>
</td>
</tr>
<tr class="AuditNoteSeparater">
<td colspan="5" height="2">
--------------------------------------------------------------------------------------------
</td>
</tr>
</table>
</div>
</body>'
I was trying using this query.
SELECT TR.AT1.query('data(span)') ,TR.AT1.query('*') ,TR.AT1.value('.','varchar(max)')
FROM #xml.nodes('/body/div/table') as T(N)
cross apply T.N.nodes('./tr/td') as TR(AT1)
cross apply TR.AT1.nodes('.') as para(p1)
Inside body tag I am getting multiple tables. first 3 tag(can be different) is table information. Next row with class="AuditNoteSubHeader" is table header and after it all class="AuditNoteText" contains table data. I need to extract this all information. Can any one please help on this ?
My expected output is:
for AuditNoteText I am getting multiple rows, So to differentiate it I had given numbers like AuditNoteText1, AuditNoteText2.
Your expected output is not the best format in my eyes. If this is not an external need, you might try something like this:
;WITH AllTr AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowIndex
,tr.value('#class','nvarchar(max)') AS trClass
,tr.query('.') AS trNode
FROM #xml.nodes('//table/tr') A(tr)
)
,AllTd AS
(
SELECT AllTr.*
,ROW_NUMBER() OVER(PARTITION BY RowIndex ORDER BY (SELECT NULL)) AS ColumnIndex
,td.value('(.//*/#class)[1]','nvarchar(max)') AS tdClass
,td.value('(.//text())[1]','nvarchar(max)') AS tdText
FROM AllTr
OUTER APPLY trNode.nodes('tr/td[.//text()]') A(td)
)
SELECT RowIndex
,ColumnIndex
,trClass
,tdClass
,tdText
FROM AllTd;
This will provide a row counter and a partitioned column counter. This might be better than name numbered class names.
;WITH C1 AS (
SELECT ISNULL(T.N.value('#class', 'varchar(50)'), TR1.AT1.value('#class', 'varchar(50)')) Hdr
, CONVERT(VARCHAR, DENSE_RANK() OVER ( PARTITION BY TR1.AT1 ORDER BY N )-1) AS HdrNum
, TR.AT1.value('.', 'varchar(max)') AS Data
FROM #xml.nodes('/body/div/table/tr,/body/div/table/tr/td/span') AS T ( N )
CROSS APPLY T.N.nodes('./td') AS TR ( AT1 )
OUTER APPLY T.N.nodes('./td/span') AS TR1 ( AT1 )
WHERE TR.AT1.value('.', 'varchar(max)') NOT LIKE '%---%'
AND TR.AT1.value('.', 'varchar(max)') <> ''
)
SELECT Hdr + CASE WHEN HdrNum = '0' THEN '' ELSE HdrNum END AS Hdr
, Data
FROM C1 ORDER BY hdr

Not getting SQLQuery quite right - Double info

I use this QUERY
SELECT id_mov, movimientos.id_expte, expte.id_expte, id_dr, detalle, fecha, plazo, expte
FROM movimientos
JOIN expte ON expte.id_expte=expte.id_expte
ORDER BY fecha DESC
And get this response
<table class="table" id="table">
<thead style="background-color:#337ab7">
<tr>
<th>Fecha</th>
<th>Movimiento</th>
<th>Expediente</th>
</tr>
</thead>
<tbody>
<tr>
<td>2016-02-10</td>
<td>Inicio demanda - Adj bono profesional, tasa y aporte.</td>
<td>351516</td>
</tr>
</tbody><tbody>
<tr>
<td>2016-02-10</td>
<td>Inicio demanda - Prox mov adjuntar bonos y demas cosas.</td>
<td>351516</td>
</tr>
</tbody><tbody>
<tr>
<td>2016-02-10</td>
<td>Inicio demanda - Adj bono profesional, tasa y aporte.</td>
<td>134512</td>
</tr>
</tbody><tbody>
<tr>
<td>2016-02-10</td>
<td>Inicio demanda - Prox mov adjuntar bonos y demas cosas.</td>
<td>134512</td>
</tr>
</tbody></table>
Now, my problem is that MOVIMIENTOS table has only 2 records but when i echo my query results with a WHILE it returns a list of 4 registries, when it should just be 2.
Any help is much apreciated. I'm new at this.
You don't join the table on the correct fields .. try using
SELECT id_mov, movimientos.id_expte, expte.id_expte, id_dr, detalle,
fecha, plazo, expte
FROM movimientos
JOIN expte ON movimientos.id_expte=expte.id_expte
ORDER BY fecha DESC

Table responsive layout CSS / HTML

I have not found the exact example for this so please point me to a link if you have. I had also made a mistake in my prev question so I awarded a correct answer but I still need help!
I want to make a table in HTML be responsive as follows - is it possible with CSS?
<table>
<thead>
<tr>
<td>HEADER Data 1</td>
<td>HEADER Data 2</td>
<td>HEADER Data 3</td>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1 Data 1</td>
<td>Row 1 Data 2</td>
<td>Row 1 Data 3</td>
</tr>
<tr>
<td>Row 2 Data 1</td>
<td>Row 2 Data 2</td>
<td>Row 2 Data 3</td>
</tr>
<tr>
<td>Row 3 Data 1</td>
<td>Row 3 Data 2</td>
<td>Row 3 Data 3</td>
</tr>
</tbody>
</table>
On small screens I want the table responsive so that is places the data as follows:
FROM THIS:
HEADER Data 1 HEADER Data 2 HEADER Data 3
Row 1 Data 1 Row 1 Data 2 Row 1 Data 3
Row 2 Data 1 Row 2 Data 2 Row 2 Data 3
Row 3 Data 1 Row 3 Data 2 Row 3 Data 3
TO THIS:
HEADER Data 1
Row 1 Data 1
Row 2 Data 1
Row 3 Data 1
HEADER Data 2
Row 1 Data 2
Row 2 Data 2
Row 3 Data 2
HEADER Data 3
Row 1 Data 3
Row 2 Data 3
Row 3 Data 3
To split a table into blocks of its columns is not possible with CSS. Therefore Javascript is needed. Like so:
<body>
<h1>Test</h1>
<table id="responsiveTable">
<thead>
<tr>
<td>HEADER Data 1</td>
<td>HEADER Data 2</td>
<td>HEADER Data 3</td>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1 Data 1</td>
<td>Row 1 Data 2</td>
<td>Row 1 Data 3</td>
</tr>
<tr>
<td>Row 2 Data 1</td>
<td>Row 2 Data 2</td>
<td>Row 2 Data 3</td>
</tr>
<tr>
<td>Row 3 Data 1</td>
<td>Row 3 Data 2</td>
<td>Row 3 Data 3</td>
</tr>
</tbody>
</table>
<hr>
<script>
var table = document.getElementById("responsiveTable");
var changeTable = function(e) {
if (document.body.clientWidth < 400) {
if (document.getElementById("responsiveTable")) {
var tr = null;
var td = null;
var cols = [];
for ( i=0; i<table.getElementsByTagName("tr").length; i++ ) {
tr = table.getElementsByTagName("tr")[i];
for ( j=0; j<tr.getElementsByTagName("td").length; j++) {
td = tr.getElementsByTagName("td")[j];
if(cols[j]==null) cols[j]=[];
cols[j][i] = td;
}
}
var divWrapper = document.createElement("div");
divWrapper.id = "divWrapper";
var divCol = null;
var divData = null;
for ( j=0; j<cols.length; j++ ) {
divCol = document.createElement("div");
for ( i=0; i<cols[j].length; i++ ) {
divData = document.createElement("div");
divData.innerHTML = cols[j][i].innerHTML;
divCol.appendChild(divData);
}
divWrapper.appendChild(divCol);
}
document.body.replaceChild(divWrapper, table);
}
} else if (document.getElementById("divWrapper")) {
document.body.replaceChild(table, document.getElementById("divWrapper"));
}
}
window.addEventListener("load", changeTable, true);
window.addEventListener("resize", changeTable, true);
</script>
</body>
Fiddle: http://jsfiddle.net/ch3sqx8j/
Greetings
Axel